myfirst_niosii.vhd 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.ALL;
  3. use IEEE.numeric_std.ALL;
  4. use IEEE.STD_LOGIC_UNSIGNED.ALL;
  5. -- top level entity myfirst_niosii
  6. entity myfirst_niosii is port (
  7. clk: in std_logic; -- 50 MHz
  8. rst: in std_logic; -- rst switch
  9. pio_led: out std_logic_vector(31 downto 0); -- LEDs of dev board
  10. buttons: in std_logic_vector(7 downto 0); -- push buttons
  11. matrix_rows: out std_logic_vector(11 downto 0); -- LED row driver, active high
  12. matrix_cols: out std_logic_vector(7 downto 0); -- LED colunm driver, active high
  13. lcd_16207_ext_RS : out std_logic; -- RS
  14. lcd_16207_ext_RW : out std_logic; -- RW
  15. lcd_16207_ext_data : inout std_logic_vector(7 downto 0) := (others => 'X'); -- data
  16. lcd_16207_ext_E : out std_logic
  17. );
  18. -- the state of the LEDs is stored in a 8 x 12 bit matrix
  19. -- the outer index represents the coulumn ID and the std_logic index represents the row ID
  20. type matrix_t is array(integer range 0 to 7) of std_logic_vector(11 downto 0);
  21. end myfirst_niosii;
  22. architecture behav of myfirst_niosii is
  23. -- noisII CPU IP wrapper
  24. component nios2_uc is port (
  25. clk_clk : in std_logic := 'X'; -- clk
  26. reset_reset_n : in std_logic := 'X'; -- reset_n
  27. lcd_16207_ext_RS : out std_logic; -- RS
  28. lcd_16207_ext_RW : out std_logic; -- RW
  29. lcd_16207_ext_data : inout std_logic_vector(7 downto 0) := (others => 'X'); -- data
  30. lcd_16207_ext_E : out std_logic; -- E
  31. pio_led_ext_conn_export : out std_logic_vector(31 downto 0); -- dev board LEDs
  32. pio_button_ext_conn_export : in std_logic_vector(7 downto 0) := (others => 'X'); -- dev board buttons
  33. pio_matrix_ext_conn_export : out std_logic_vector(19 downto 0) -- matrix instruction
  34. -- matrix instruction contains three parts:
  35. -- 20 16 12 8 4 0
  36. -- XXXX CCCC RRRR RRRR RRRR
  37. --
  38. -- X: 19 downto 16: unused
  39. -- C: 15 downto 12: column number
  40. -- R: 11 downto 0: row data
  41. --
  42. -- column number:
  43. -- 0000: don't set anything
  44. -- 0001: set column 0 to row data
  45. -- 0010: set column 1 to row data
  46. -- 0011: set column 2 to row data
  47. -- ...
  48. );
  49. end component nios2_uc;
  50. -- signals for debouncing
  51. -- previous button state
  52. signal button_states: std_logic_vector(7 downto 0);
  53. -- button polling clock: 50Mhz / 2**20 = 47.7 Hz
  54. signal button_timer: integer range 0 to 2**20-1 := 0;
  55. -- matrix multiplexing clock:
  56. -- 50Mhz / 2**20 = 1526 Hz = 1 / 0.66 ms per column
  57. -- 1526 Hz / 8 = 190 Hz matrix refresh rate
  58. signal matrix_timer: integer range 0 to 2**15-1 := 0;
  59. -- column index signal
  60. signal matrix_col_index: integer range 0 to 7 := 0;
  61. -- matrix signal
  62. signal matrix_s: matrix_t;
  63. -- matrix instruction signal
  64. signal pio_matrix_s: std_logic_vector(19 downto 0);
  65. begin
  66. u0: component nios2_uc
  67. port map (
  68. clk_clk => clk,
  69. pio_led_ext_conn_export => pio_led,
  70. reset_reset_n => rst,
  71. pio_matrix_ext_conn_export => pio_matrix_s,
  72. pio_button_ext_conn_export => button_states
  73. );
  74. -- copies the row data according to instructions from CPU
  75. matrix_set: process(clk, rst)
  76. variable col_id : integer range 0 to 8;
  77. begin
  78. if rst = '0' then
  79. matrix_s <= (
  80. "111110011111",
  81. "000100000101",
  82. "010000000111",
  83. "111110000000",
  84. "000000011111",
  85. "111110010001",
  86. "101010011111",
  87. "111010000000"
  88. );
  89. elsif rising_edge(clk) then
  90. col_id := to_integer(unsigned(pio_matrix_s(15 downto 12)));
  91. if col_id > 0 then
  92. matrix_s(col_id-1) <= pio_matrix_s(11 downto 0);
  93. end if;
  94. end if;
  95. end process;
  96. -- copies rows from matrix_s to the outputs
  97. matrix_multiplex: process(clk, rst)
  98. begin
  99. if rst = '0' then
  100. matrix_rows <= "111111111111";
  101. matrix_cols <= "11111111";
  102. matrix_timer <= 0;
  103. matrix_col_index <= 0;
  104. elsif rising_edge(clk) then
  105. -- set outputs to zero at timer overflow
  106. -- avoids ghosting of display
  107. if matrix_timer = 2**15-1 then
  108. matrix_timer <= 0;
  109. if matrix_col_index = 7 then
  110. matrix_col_index <= 0;
  111. else
  112. matrix_col_index <= matrix_col_index + 1;
  113. end if;
  114. matrix_cols <= (others => '0');
  115. matrix_rows <= (others => '0');
  116. -- write actual data only 50MHz / 2**11 = 1 / 0.04 ms after setting outputs to zero
  117. elsif matrix_timer = 2**11-1 then
  118. matrix_cols(matrix_col_index) <= '1';
  119. matrix_rows <= matrix_s(matrix_col_index);
  120. matrix_timer <= matrix_timer + 1;
  121. -- else do nothing
  122. else
  123. matrix_timer <= matrix_timer + 1;
  124. end if;
  125. end if;
  126. end process;
  127. -- this process polls the buttons at 47.7 Hz
  128. -- edge detection is done in software
  129. button_debounce: process(clk, rst)
  130. begin
  131. if rst = '0' then
  132. button_timer <= 0;
  133. elsif rising_edge(clk) then
  134. if button_timer = 2**20-1 then
  135. button_timer <= 0;
  136. -- update button states
  137. for id in 0 to 7 loop
  138. button_states(id) <= buttons(id);
  139. end loop;
  140. else
  141. button_timer <= button_timer + 1;
  142. end if;
  143. end if;
  144. end process;
  145. end behav;