ネット上で見つけたシンプルなキーボードインターフェイスを自分の用途に合わせて変更しています。アイデアは、新しいスキャンコードがあるときはいつでも、「Scan_Dav」という名前の出力をハイにしてからローにするというものです。したがって、Scan_Davをクロックとして別のモジュールに送信すると、新しいScanCodeが押されるたびに、そのモジュールのクロックが立ち上がりエッジになります。私の考え方に誤りはありますか?私はそれを試し、scancodeとscan_davをプロジェクトの残りの部分に向けたため(指定されたスキャンコードと並んで文字を書き込み、7セグメントディスプレイに表示します)、表示されるテキストには各文字が2つ含まれていました(つまり、FLYを書くとテキストはFFLLYYのようでした)。エラーがない場合は、コードを共有して、なぜ機能しないのかを尋ねます。ありがとう :)
編集:これは、Scan_Davの値に従ってシフトが行われる場所です
signal bytes : std_logic_vector(63 downto 0);
signal Scan_Dav_Sync: std_logic_vector(1 downto 0):="00";
signal Previous_Scan_Dav: std_logic:='0';
begin
process (clk) begin --, Scan_Dav) begin
if rising_edge(clk) then
Scan_Dav_Sync(0) <= Scan_Dav;
Scan_Dav_Sync(1) <= Scan_Dav_Sync(0);
Previous_Scan_Dav <= Scan_Dav_Sync(1);
if (Previous_Scan_Dav = '0') and (Scan_Dav_Sync(1) = '1') then
bytes <= bytes (bytes'high-8 downto 0) & Data_in;
end if;
end if;
end process;
これがScan_Davの由来であり、コードはここから取得されます:(フィルタリング部分は無視してかまいません)
Architecture Behavioral of KeyboardController is
signal PS2_Datr : std_logic;
subtype Filter_t is std_logic_vector(7 downto 0);
signal Filter : Filter_t;
signal Fall_Clk : std_logic;
signal Bit_Cnt : unsigned (3 downto 0);
signal Scan_DAVi : std_logic;
signal S_Reg : std_logic_vector(8 downto 0);
signal PS2_Clk_f : std_logic;
Type State_t is (Idle, Shifting);
signal State : State_t;
signal Scan_Code : std_logic_vector(7 downto 0);
signal Flag : std_logic:='0';
begin
process (Clk,Reset)
begin
if Reset='1' then
PS2_Datr <= '0';
PS2_Clk_f <= '0';
Filter <= (others=>'0');
Fall_Clk <= '0';
elsif rising_edge (Clk) then
PS2_Datr <= PS2_Data and PS2_Data; -- also turns 'H' into '1'
Fall_Clk <= '0';
Filter <= (PS2_Clk and PS2_CLK) & Filter(Filter'high downto 1);
if Filter = Filter_t'(others=>'1') then
PS2_Clk_f <= '1';
elsif Filter = Filter_t'(others=>'0') then
PS2_Clk_f <= '0';
if PS2_Clk_f = '1' then
Fall_Clk <= '1';
end if;
end if;
end if;
end process;
-- This simple State Machine reads in the Serial Data
-- coming from the PS/2 peripheral.
process(Clk,Reset)
begin
if Reset='1' then
State <= Idle;
Bit_Cnt <= (others => '0');
S_Reg <= (others => '0');
Scan_Code <= (others => '0');
Scan_Out <= (others => '0');
Scan_Davi <= '0';
elsif rising_edge (Clk) then
-- if Scan_Davi = '1' then
-- Scan_Davi <= '0';
-- end if;
case State is
when Idle =>
Bit_Cnt <= (others => '0');
-- note that we dont need to clear the Shift Register
if Fall_Clk='1' and PS2_Datr='0' then -- Start bit
State <= Shifting;
end if;
when Shifting =>
if Bit_Cnt >= 9 then
if Fall_Clk='1' then -- Stop Bit
Scan_Code <= S_Reg(7 downto 0);
if (Flag = '1' and Scan_Code /= "11110000") then
--to ignore makecode
Scan_Out <= Scan_Code;
Flag <= '0';
Scan_Davi <= '1';
end if;
if (Flag = '0' and Scan_Code = "11110000") then
--to ignore F0
Flag <= '1';
Scan_Davi <= '0';
end if;
State <= Idle;
end if;
elsif Fall_Clk='1' then
Bit_Cnt <= Bit_Cnt + 1;
S_Reg <= PS2_Datr & S_Reg (S_Reg'high downto 1); -- Shift right
end if;
when others => -- never reached
State <= Idle;
end case;
end if;
end process;
Scan_DAV <= Scan_DAVi;
end Behavioral;
更新:残っている唯一の問題は、文字とテキストの表示とシフトの遅延です。VHDLを書いている間、Vを押しても何も得られません。次に、Hを押すとVが得られ、そのようになります。最後の文字は別のキーを押すまで表示されません。Scan_Davの問題のようですが、それが何であるかを解決できません。どんな助けでもありがたいです。