Revision 256
Added by markw about 11 years ago
| common/a8core/pokey.vhdl | ||
|---|---|---|
| 
     	RESET_N : IN STD_LOGIC;
 
   | 
||
| 
     | 
||
| 
     	-- keyboard interface
 
   | 
||
| 
     --	KBCODE : IN STD_LOGIC_VECTOR(7 downto 0);
 
   | 
||
| 
     --	KEY_HELD : IN STD_LOGIC;
 
   | 
||
| 
     --	SHIFT_PRESSED : IN STD_LOGIC;
 
   | 
||
| 
     --	BREAK_PRESSED : IN STD_LOGIC;
 
   | 
||
| 
     --	KEY_INTERRUPT : IN STD_LOGIC;
 
   | 
||
| 
     	keyboard_scan : out std_logic_vector(5 downto 0);
 
   | 
||
| 
     	keyboard_response : in std_logic_vector(1 downto 0);
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     | 
||
| 
     		keyboard_scan : out std_logic_vector(5 downto 0);
 
   | 
||
| 
     | 
||
| 
     		shift_pressed : out std_logic;
 
   | 
||
| 
     		control_pressed : out std_logic;
 
   | 
||
| 
     		break_pressed : out std_logic;
 
   | 
||
| 
     		key_held : out std_logic;
 
   | 
||
| 
     		keycode : out std_logic_vector(5 downto 0);
 
   | 
||
| 
     		other_key_irq : out std_logic
 
   | 
||
| 
     		shift_held : out std_logic;
 
   | 
||
| 
     		keycode : out std_logic_vector(7 downto 0);
 
   | 
||
| 
     		other_key_irq : out std_logic;
 
   | 
||
| 
     		break_irq : out std_logic
 
   | 
||
| 
     	);
 
   | 
||
| 
     	end component;
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     	signal keyboard_overrun_next : std_logic;
 
   | 
||
| 
     	signal keyboard_overrun_reg : std_logic;
 
   | 
||
| 
     | 
||
| 
     	signal shift_pressed : std_logic;
 
   | 
||
| 
     	signal control_pressed : std_logic;
 
   | 
||
| 
     	signal break_pressed : std_logic;
 
   | 
||
| 
     	signal shift_held : std_logic;
 
   | 
||
| 
     	signal break_irq : std_logic;
 
   | 
||
| 
     	signal key_held : std_logic;
 
   | 
||
| 
     	signal other_key_irq : std_logic;
 
   | 
||
| 
     | 
||
| 
     	signal kbcode : std_logic_vector(5 downto 0);
 
   | 
||
| 
     	signal kbcode : std_logic_vector(7 downto 0);
 
   | 
||
| 
     | 
||
| 
     	-- pots
 
   | 
||
| 
     	signal pot0_next : std_logic_vector(7 downto 0);
 
   | 
||
| ... | ... | |
| 
     	end process;
 
   | 
||
| 
     | 
||
| 
     	-- Read from registers
 
   | 
||
| 
     	process(addr_decoded,kbcode,control_pressed,RAND_OUT,IRQST_REG,KEY_HELD,SHIFT_PRESSED,sio_in_reg,serin_reg,keyboard_overrun_reg, serial_ip_framing_reg, serial_ip_overrun_reg, waiting_for_start_bit, pot_in, pot0_reg, pot1_reg, pot2_reg, pot3_reg, pot4_reg, pot5_reg, pot6_reg, pot7_reg)
 
   | 
||
| 
     	process(addr_decoded,kbcode,RAND_OUT,IRQST_REG,key_held,shift_held,sio_in_reg,serin_reg,keyboard_overrun_reg, serial_ip_framing_reg, serial_ip_overrun_reg, waiting_for_start_bit, pot_in, pot0_reg, pot1_reg, pot2_reg, pot3_reg, pot4_reg, pot5_reg, pot6_reg, pot7_reg)
 
   | 
||
| 
     	begin
 
   | 
||
| 
     		data_out <= X"FF";
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     		if(addr_decoded(9) = '1') then --KBCODE
 
   | 
||
| 
     			data_out <= control_pressed&shift_pressed&kbcode;
 
   | 
||
| 
     			data_out <= kbcode;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     		if(addr_decoded(10) = '1') then -- RANDOM
 
   | 
||
| ... | ... | |
| 
     		end if;		
 
   | 
||
| 
     | 
||
| 
     		if (addr_decoded(15) = '1') then --SKSTAT
 
   | 
||
| 
     			data_out <= not(serial_ip_framing_reg)¬(keyboard_overrun_reg)¬(serial_ip_overrun_reg)&sio_in_reg¬(SHIFT_PRESSED)¬(KEY_HELD)&waiting_for_start_bit&"1";
 
   | 
||
| 
     			data_out <= not(serial_ip_framing_reg)¬(keyboard_overrun_reg)¬(serial_ip_overrun_reg)&sio_in_reg¬(shift_held)¬(key_held)&waiting_for_start_bit&"1";
 
   | 
||
| 
     		end if;		
 
   | 
||
| 
     | 
||
| 
     	end process;
 
   | 
||
| 
     | 
||
| 
     	-- Fire interrupts
 
   | 
||
| 
     	process (irqen_reg, irqst_reg, audf0_pulse, audf1_pulse, audf3_pulse, other_key_irq, serial_ip_ready_interrupt, serout_active_reg, serial_op_needed_interrupt, break_pressed)
 
   | 
||
| 
     	process (irqen_reg, irqst_reg, audf0_pulse, audf1_pulse, audf3_pulse, other_key_irq, serial_ip_ready_interrupt, serout_active_reg, serial_op_needed_interrupt, break_irq)
 
   | 
||
| 
     	begin
 
   | 
||
| 
     		-- clear interrupts
 
   | 
||
| 
     		irqst_next <= irqst_reg or not(irqen_reg);
 
   | 
||
| ... | ... | |
| 
     			irqst_next(6) <= not(irqen_reg(6));			
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     		if (break_pressed = '1') then
 
   | 
||
| 
     		if (break_irq = '1') then
 
   | 
||
| 
     			irqst_next(7) <= not(irqen_reg(7));			
 
   | 
||
| 
     		end if;		
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     | 
||
| 
     	-- keyboard scan
 
   | 
||
| 
     	pokey_keyboard_scanner1 : pokey_keyboard_scanner
 
   | 
||
| 
     		port map (clk=>clk, reset_n=>reset_n, enable=>enable_15, keyboard_response=>keyboard_response, debounce_disable=>not(skctl_reg(0)), scan_enable=>skctl_reg(1), keyboard_scan=>keyboard_scan, shift_pressed=>shift_pressed, control_pressed=>control_pressed, break_pressed=>break_pressed, key_held=>key_held, keycode=>kbcode, other_key_irq=>other_key_irq);	
 
   | 
||
| 
     | 
||
| 
     		port map (clk=>clk, reset_n=>reset_n, enable=>enable_15, keyboard_response=>keyboard_response, debounce_disable=>not(skctl_reg(0)), scan_enable=>skctl_reg(1), keyboard_scan=>keyboard_scan, key_held=>key_held, shift_held=>shift_held, keycode=>kbcode, other_key_irq=>other_key_irq, break_irq=>break_irq);
 
   | 
||
| 
     | 
||
| 
     	-- POT scan
 
   | 
||
| 
     	process(potgo_write, pot_reset_reg, pot_counter_reg, pot_in, enable_15, enable_179, skctl_reg, pot0_reg, pot1_reg, pot2_reg, pot3_reg, pot4_reg, pot5_reg, pot6_reg, pot7_reg)
 
   | 
||
| 
     	begin	
 
   | 
||
| common/a8core/pokey_keyboard_scanner.vhdl | ||
|---|---|---|
| 
     | 
||
| 
     	keyboard_scan : out std_logic_vector(5 downto 0);
 
   | 
||
| 
     | 
||
| 
     	shift_pressed : out std_logic;
 
   | 
||
| 
     	control_pressed : out std_logic;
 
   | 
||
| 
     	break_pressed : out std_logic;
 
   | 
||
| 
     	key_held : out std_logic;
 
   | 
||
| 
     	keycode : out std_logic_vector(5 downto 0);
 
   | 
||
| 
     	other_key_irq : out std_logic
 
   | 
||
| 
     	shift_held : out std_logic;
 
   | 
||
| 
     	keycode : out std_logic_vector(7 downto 0);
 
   | 
||
| 
     	other_key_irq : out std_logic;
 
   | 
||
| 
     	break_irq : out std_logic
 
   | 
||
| 
     );
 
   | 
||
| 
     end pokey_keyboard_scanner;
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     	signal compare_latch_next : std_logic_vector(5 downto 0);
 
   | 
||
| 
     	signal compare_latch_reg : std_logic_vector(5 downto 0);
 
   | 
||
| 
     | 
||
| 
     	signal keycode_latch_next : std_logic_vector(5 downto 0);
 
   | 
||
| 
     	signal keycode_latch_reg : std_logic_vector(5 downto 0);
 
   | 
||
| 
     	signal keycode_latch_next : std_logic_vector(7 downto 0);
 
   | 
||
| 
     	signal keycode_latch_reg : std_logic_vector(7 downto 0);
 
   | 
||
| 
     | 
||
| 
     	signal irq_next : std_logic;
 
   | 
||
| 
     	signal irq_reg : std_logic;
 
   | 
||
| 
     | 
||
| 
     	signal break_irq_next : std_logic;
 
   | 
||
| 
     	signal break_irq_reg : std_logic;
 
   | 
||
| 
     | 
||
| 
     	signal key_held_next : std_logic;
 
   | 
||
| 
     	signal key_held_reg : std_logic;
 
   | 
||
| ... | ... | |
| 
     			key_held_reg <= '0';
 
   | 
||
| 
     			state_reg <= state_wait_key;
 
   | 
||
| 
     			irq_reg <= '0';
 
   | 
||
| 
     			break_irq_reg <= '0';
 
   | 
||
| 
     		elsif (clk'event and clk = '1') then
 
   | 
||
| 
     			bincnt_reg <= bincnt_next;
 
   | 
||
| 
     			state_reg <= state_next;
 
   | 
||
| ... | ... | |
| 
     			key_held_reg <= key_held_next;
 
   | 
||
| 
     			state_reg <= state_next;
 
   | 
||
| 
     			irq_reg <= irq_next;
 
   | 
||
| 
     			break_irq_reg <= break_irq_next;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     	end process;
 
   | 
||
| 
     | 
||
| 
     	process (enable, keyboard_response, scan_enable, key_held_reg, my_key, state_reg,bincnt_reg, compare_latch_reg, break_pressed_reg, shift_pressed_reg, control_pressed_reg, keycode_latch_reg, debounce_disable)
 
   | 
||
| 
     	process (enable, keyboard_response, scan_enable, key_held_reg, my_key, state_reg,bincnt_reg, compare_latch_reg, break_pressed_reg, shift_pressed_reg, break_irq_reg, control_pressed_reg, keycode_latch_reg, debounce_disable)
 
   | 
||
| 
     	begin
 
   | 
||
| 
     		bincnt_next <= bincnt_reg;
 
   | 
||
| 
     		state_next <= state_reg;
 
   | 
||
| 
     		compare_latch_next <= compare_latch_reg;
 
   | 
||
| 
     		irq_next <= '0';
 
   | 
||
| 
     		break_irq_next <= '0';
 
   | 
||
| 
     		break_pressed_next <= break_pressed_reg;
 
   | 
||
| 
     		shift_pressed_next <= shift_pressed_reg;
 
   | 
||
| 
     		control_pressed_next <= control_pressed_reg;
 
   | 
||
| ... | ... | |
| 
     		key_held_next <= key_held_reg;
 
   | 
||
| 
     | 
||
| 
     		my_key <= '0';
 
   | 
||
| 
     		if (bincnt_reg = compare_latch_reg) then
 
   | 
||
| 
     		if (bincnt_reg = compare_latch_reg or debounce_disable='1') then
 
   | 
||
| 
     			my_key <= '1';
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     			case state_reg is
 
   | 
||
| 
     			when state_wait_key =>
 
   | 
||
| 
     				if (keyboard_response(0) = '0') then -- detected key press
 
   | 
||
| 
     					state_next <= state_key_bounce;
 
   | 
||
| 
     					compare_latch_next <= bincnt_reg;
 
   | 
||
| 
     					if (debounce_disable = '1') then
 
   | 
||
| 
     						keycode_latch_next <= control_pressed_reg&shift_pressed_reg&bincnt_reg;
 
   | 
||
| 
     						irq_next <= '1';
 
   | 
||
| 
     						key_held_next<= '1';
 
   | 
||
| 
     					else
 
   | 
||
| 
     						state_next <= state_key_bounce;
 
   | 
||
| 
     						compare_latch_next <= bincnt_reg;
 
   | 
||
| 
     					end if;
 
   | 
||
| 
     				end if;
 
   | 
||
| 
     | 
||
| 
     			when state_key_bounce =>
 
   | 
||
| 
     				if (keyboard_response(0) = '0') then -- detected key press
 
   | 
||
| 
     					if (my_key = '1') then -- same key
 
   | 
||
| 
     						keycode_latch_next <= compare_latch_reg;
 
   | 
||
| 
     						keycode_latch_next <= control_pressed_reg&shift_pressed_reg&compare_latch_reg;
 
   | 
||
| 
     						irq_next <= '1';
 
   | 
||
| 
     						key_held_next<= '1';
 
   | 
||
| 
     						state_next <= state_valid_key;
 
   | 
||
| ... | ... | |
| 
     				end if;
 
   | 
||
| 
     | 
||
| 
     			when state_key_debounce =>
 
   | 
||
| 
     				key_held_next<= '1';
 
   | 
||
| 
     				if (my_key = '1') then
 
   | 
||
| 
     					state_next <= state_wait_key;
 
   | 
||
| 
     					if (keyboard_response(0) = '1') then -- no longer pressed
 
   | 
||
| 
     						key_held_next<= '0';
 
   | 
||
| 
     						state_next <= state_wait_key;
 
   | 
||
| 
     					else
 
   | 
||
| 
     						state_next <= state_valid_key;
 
   | 
||
| 
     					end if;					
 
   | 
||
| 
     				end if;
 
   | 
||
| 
     | 
||
| 
     			when others=> 
 
   | 
||
| 
     				state_next <= state_wait_key; 
 
   | 
||
| 
     			end case;
 
   | 
||
| 
     | 
||
| 
     			if (debounce_disable = '1' and keyboard_response(0) = '0') then
 
   | 
||
| 
     				keycode_latch_next <= bincnt_reg;
 
   | 
||
| 
     				irq_next <= '1';
 
   | 
||
| 
     				key_held_next<= '1';
 
   | 
||
| 
     			end if;
 
   | 
||
| 
     | 
||
| 
     			break_pressed_next <= '0';
 
   | 
||
| 
     			shift_pressed_next <= '0';
 
   | 
||
| 
     			control_pressed_next <= '0';
 
   | 
||
| 
     			if (bincnt_reg(3 downto 0)  = "0000") then
 
   | 
||
| 
     				case bincnt_reg(5 downto 4) is
 
   | 
||
| 
     				when "11" =>
 
   | 
||
| ... | ... | |
| 
     				end case;
 
   | 
||
| 
     			end if;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     		if (break_pressed_next='1' and break_pressed_reg='0') then
 
   | 
||
| 
     			break_irq_next <= '1';
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     	end process;
 
   | 
||
| 
     | 
||
| 
     	-- outputs
 
   | 
||
| 
     	keyboard_scan <= not(bincnt_reg);
 
   | 
||
| 
     | 
||
| 
     	key_held <= key_held_reg;	
 
   | 
||
| 
     	shift_held <= shift_pressed_reg;
 
   | 
||
| 
     	keycode <= keycode_latch_reg;
 
   | 
||
| 
     	break_pressed <= break_pressed_reg;
 
   | 
||
| 
     	shift_pressed <= shift_pressed_reg;
 
   | 
||
| 
     	control_pressed <= control_pressed_reg;
 
   | 
||
| 
     	other_key_irq <= irq_reg;
 
   | 
||
| 
     	break_irq <= break_irq_reg;
 
   | 
||
| 
     end vhdl;
 
   | 
||
Fix shift. I hope this is correct now for both platforms... the pokey.pdf misses some details.