Delay output signal for 3 clock cycles in VHDL - delay

If the reset signal is '0' then "EN" goes high and "clr" goes low. However, if the reset signal goes high on the rising edge of the clock then "EN" goes low and "clr" goes high. I accomplished this in my code, but i need to delay the output signal produced when reset goes high[ EN = 0/ CLR = 1] for 3 more clock cycles. I tried using a counter, but it produced the same answer.
BEGIN
process ( Reset, Clk)
begin
if Reset = '0' then
En <= '1';
clr <= '0';
elsif rising_edge(Clk) then
if Reset = '1' then
En <= '0';
clr <= '1';
end if;
end if;
end process;
END description;

Delaying signals is done by a 3 bit shift register or in your case 3 chained D-FF.
Shift register as a oneliner:
architecture rtl of myEntity is
signal clr_sr : std_logic_vector(2 downto 0) := "000";
signal en_sr : std_logic_vector(2 downto 0) := "000";
signal clr_delayed : std_logic;
signal en_delayed : std_logic;
[...]
begin
[...]
process(Reset, Clk)
begin
if Reset = '0' then
en <= '1';
clr <= '0';
elsif rising_edge(Clk) then
en <= '0';
clr <= '1';
end if;
end process;
clr_sr <= clr_sr(clr_sr'high - 1 downto 0) & clr when rising_edge(Clock);
en_sr <= en_sr(en_sr'high - 1 downto 0) & en when rising_edge(Clock);
clr_delayed <= clr_sr(clr_sr'high);
en_delayed <= en_sr(en_sr'high);
[...]
end;
Or even shorter with a function sr_left to encapsulate the shift functionality:
clr_sr <= sr_left(clr_sr, clr) when rising_edge(Clock);

Related

enabling gpio pins on spartan 3

I am trying to run a dc motor using spartan 3 fpga board and i need to take out 2 pins from the board as the input pins to my motor driver. I am not able to enable them. i have already declared them as out std_logic and i have also generated a constraint file for them, but after checking the output on those pins i am getting 0volts.
what should I write in the code, do i have to declare them as signals?
please tell me how to enable them in vhdl code. below i have given my vhdl code
`entity dc_motor is
port ( clk : in std_logic;
rst : in std_logic;
io_pin1: out std_logic;
io_pin2 : out std_logic);
end dc_motor;
architecture Behavioral of dc_motor is
begin
process(rst,clk)
variable i : integer := 0;
begin
if rst = '1' then
if clk'event and clk = '1' then
--enable <= '1';
if i <= 1005000 then
i := i + 1;
io_pin1 <= '0';
io_pin2 <= '0';
elsif i > 1005000 and i < 1550000 then
i := i + 1;
io_pin1 <= '1';
io_pin2 <= '0';
elsif i = 1550000 then
i := 0;
end if;
end if;
end if;
end process;
end Behavioral;
`

VHDL - ModelSim testbench simulation freezes when sending "run"

I have a problem regarding a testbench I am developing for an hardware butterfly algorithm for calculating the Fourier transform.
What I'm attempting to do is reading a series of input data files (32-bit vectors) and writing the output in some other output files.
The input files are Ar.txt, Ai.txt, Br.txt, Bi.txt, Wr.txt and Wi.txt.
The output files are Ar_OUT_TB.txt, Ai_OUT_TB.txt, Br_OUT_TB.txt, Bi_OUT_TB.txt.
But when I try to simulate with ModelSim, the program simply freezes: I can still do some stuff, like opening another project/file etc., but there's no waveform showing, and also the command line is missing. I also tried to simulate an older VHDL project of mine and it did simulate, so I guess the problem is within this code.
These are the main processes (EDIT: I'm also adding the rest of the code, for understanding):
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE STD.TEXTIO.ALL;
ENTITY BUTTERFLY_TESTBENCH IS
END BUTTERFLY_TESTBENCH;
ARCHITECTURE DEVICE OF BUTTERFLY_TESTBENCH IS
COMPONENT progetto_butterfly
GENERIC(N_IN, N_OUT: INTEGER := 32;
N_BUSES: INTEGER := 63);
PORT(START, CLK, MAIN_RST_N: IN STD_LOGIC;
DATA_IN, Wr_IN, Wi_IN: IN SIGNED(N_IN-1 DOWNTO 0);
DATA_OUT: OUT SIGNED(N_IN-1 DOWNTO 0);
DONE: OUT STD_LOGIC);
END COMPONENT;
CONSTANT N_IN: INTEGER := 32;
CONSTANT N_OUT: INTEGER := 32;
SIGNAL TEST_DATA_IN, TEST_Wr_IN, TEST_Wi_IN: SIGNED(N_IN-1 DOWNTO 0);
SIGNAL TEST_OUTPUT: SIGNED(N_OUT-1 DOWNTO 0);
SIGNAL CLK: STD_LOGIC;
SIGNAL TEST_START, TEST_RST, TEST_DONE: STD_LOGIC;
FILE Ar_IN_FILE: TEXT OPEN READ_MODE IS "Ar.txt";
FILE Ai_IN_FILE: TEXT OPEN READ_MODE IS "Ai.txt";
FILE Br_IN_FILE: TEXT OPEN READ_MODE IS "Br.txt";
FILE Bi_IN_FILE: TEXT OPEN READ_MODE IS "Bi.txt";
FILE WR_FILE: TEXT OPEN READ_MODE IS "Wr.txt";
FILE WI_FILE: TEXT OPEN READ_MODE IS "Wi.txt";
FILE Ar_OUT: TEXT OPEN WRITE_MODE IS "Ar_OUT_TB.txt";
FILE Ai_OUT: TEXT OPEN WRITE_MODE IS "Ai_OUT_TB.txt";
FILE Br_OUT: TEXT OPEN WRITE_MODE IS "Br_OUT_TB.txt";
FILE Bi_OUT: TEXT OPEN WRITE_MODE IS "Bi_OUT_TB.txt";
BEGIN
BUTTERFLY_TEST_COMPONENT: progetto_butterfly PORT MAP(START => TEST_START, CLK => CLK, MAIN_RST_N => TEST_RST,
DATA_IN => TEST_DATA_IN, Wr_IN => TEST_Wr_IN, Wi_IN => TEST_Wi_IN,
DATA_OUT => TEST_OUTPUT, DONE => TEST_DONE);``
DATA_IN_PROCESS: PROCESS
VARIABLE DATA_BUFFER: LINE;
VARIABLE DATA_STIMULUS: BIT_VECTOR(N_IN-1 DOWNTO 0);
BEGIN
IF NOT (ENDFILE(Br_IN_FILE)) THEN
IF(TEST_START = '1' AND TEST_RST = '1') THEN
READLINE(Br_IN_FILE,DATA_BUFFER);
READ(DATA_BUFFER,DATA_STIMULUS);
TEST_DATA_IN <= SIGNED(TO_STDLOGICVECTOR(DATA_STIMULUS));
WAIT UNTIL CLK'EVENT AND CLK = '1';
READLINE(Bi_IN_FILE,DATA_BUFFER);
READ(DATA_BUFFER,DATA_STIMULUS);
TEST_DATA_IN <= SIGNED(TO_STDLOGICVECTOR(DATA_STIMULUS));
WAIT UNTIL RISING_EDGE(CLK);
READLINE(Ar_IN_FILE,DATA_BUFFER);
READ(DATA_BUFFER,DATA_STIMULUS);
TEST_DATA_IN <= SIGNED(TO_STDLOGICVECTOR(DATA_STIMULUS));
WAIT UNTIL RISING_EDGE(CLK);
READLINE(Ai_IN_FILE,DATA_BUFFER);
READ(DATA_BUFFER,DATA_STIMULUS);
TEST_DATA_IN <= SIGNED(TO_STDLOGICVECTOR(DATA_STIMULUS));
WAIT FOR 12 ns;
ELSE
TEST_DATA_IN <= (OTHERS => '0');
END IF;
END IF;
END PROCESS;
WR_PROCESS: PROCESS
VARIABLE wr_buf: LINE;
VARIABLE WR_STIMULUS: BIT_VECTOR(N_IN-1 DOWNTO 0);
BEGIN
WHILE NOT (ENDFILE(WR_FILE)) LOOP
IF(TEST_START = '1' AND TEST_RST = '1') THEN
READLINE(WR_FILE,wr_buf);
READ(wr_buf,WR_STIMULUS);
TEST_Wr_IN <= SIGNED(TO_STDLOGICVECTOR(WR_STIMULUS));
WAIT FOR 20 ns;
END IF;
END LOOP;
END PROCESS;
WRITING_PROCESS: PROCESS
VARIABLE STRING_LINE: STRING(N_OUT DOWNTO 1);
VARIABLE OUT_LINE: LINE;
VARIABLE I: INTEGER;
BEGIN
WAIT FOR 12 ns;
WHILE (TEST_START = '1' AND TEST_RST = '1') LOOP
FOR I IN N_OUT-1 DOWNTO 0 LOOP
IF(TEST_OUTPUT(I) = '0') THEN
STRING_LINE(I+1) := '0';
ELSE
STRING_LINE(I+1) := '1';
END IF;
END LOOP;
WRITE(OUT_LINE,STRING_LINE);
WRITELINE(Br_OUT,OUT_LINE);
WAIT UNTIL RISING_EDGE(CLK);
FOR I IN N_OUT-1 DOWNTO 0 LOOP
IF(TEST_OUTPUT(I) = '0') THEN
STRING_LINE(I+1) := '0';
ELSE
STRING_LINE(I+1) := '1';
END IF;
END LOOP;
WRITE(OUT_LINE,STRING_LINE);
WRITELINE(Bi_OUT,OUT_LINE);
WAIT UNTIL RISING_EDGE(CLK);
FOR I IN N_OUT-1 DOWNTO 0 LOOP
IF(TEST_OUTPUT(I) = '0') THEN
STRING_LINE(I+1) := '0';
ELSE
STRING_LINE(I+1) := '1';
END IF;
END LOOP;
WRITE(OUT_LINE,STRING_LINE);
WRITELINE(Ar_OUT,OUT_LINE);
WAIT UNTIL RISING_EDGE(CLK);
FOR I IN N_OUT-1 DOWNTO 0 LOOP
IF(TEST_OUTPUT(I) = '0') THEN
STRING_LINE(I+1) := '0';
ELSE
STRING_LINE(I+1) := '1';
END IF;
END LOOP;
WRITE(OUT_LINE,STRING_LINE);
WRITELINE(Ai_OUT,OUT_LINE);
END LOOP;
END PROCESS;
CLK_PROCESS: PROCESS
BEGIN
CLK <= '1';
WAIT FOR 2 ns;
CLK <= '0';
WAIT FOR 2 ns;
END PROCESS;
TEST_RST <= '0', '1' AFTER 2 ns;
TEST_START <= '0', '1' AFTER 3 ns;
END ARCHITECTURE;
Is something done wrong? I can't see what I'm missing.
Your DATA_IN_PROCESS process is an infinite loop. As long as as the condition TEST_START = '1' AND TEST_RST = '1' is not met, the process keeps on running, without incrementing simulated time. It eats up simulator time and simuated time does not increase.
Solve this by adding WAIT UNTIL RISING_EDGE(CLK); in the else clause.
Other problems with your code are listed here: http://www.sigasi.com/vhdl-code-check?ID=27869561
Your processes either need a sensitivity list or a WAIT statement.
After building an MVCe from your example I found that it appears an input file you're reading is too short, revealing faults in two of your processes (data_in_process and wr_process).
library ieee;
use std.textio.all;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity sometb is
end entity;
architecture foo of sometb is
constant n_in: integer := 8;
signal test_start: std_logic := '1';
signal test_rst: std_logic := '1';
file br_in_file: text open READ_MODE is "Br.txt";
signal test_data_in: signed(n_in - 1 downto 0);
signal clk: std_logic := '0';
file bi_in_file: text open READ_MODE is "Bi.txt";
file ar_in_file: text open READ_MODE is "Ar.txt";
file ai_in_file: text open READ_MODE is "Ai.txt";
file wr_file: text open READ_MODE is "Wr.txt";
signal test_wr_in: signed(n_in - 1 downto 0);
constant n_out: integer:= 8;
signal test_output: std_logic_vector(n_out - 1 downto 0);
file br_out: text open WRITE_MODE is "Br_OUT_TB.txt";
file bi_out: text open WRITE_MODE is "Bi_OUT_TB.txt";
file ar_out: text open WRITE_MODE is "Ar_OUT_TB.txt";
file ai_out: text open WRITE_MODE is "Bi_OUT_TB.txt";
begin
CLOCK:
process
begin
wait for 6 ns;
clk <= not clk;
end process;
data_in_process:
process
variable data_buffer: line;
variable data_stimulus: bit_vector(n_in-1 downto 0);
begin
if not endfile(br_in_file) then
if test_start = '1' and test_rst = '1' then
readline(br_in_file,data_buffer);
read(data_buffer,data_stimulus);
test_data_in <= signed(to_stdlogicvector(data_stimulus));
wait until clk'event and clk = '1';
readline(bi_in_file,data_buffer);
read(data_buffer,data_stimulus);
test_data_in <= signed(to_stdlogicvector(data_stimulus));
wait until rising_edge(clk);
readline(ar_in_file,data_buffer);
read(data_buffer,data_stimulus);
test_data_in <= signed(to_stdlogicvector(data_stimulus));
wait until rising_edge(clk);
readline(ai_in_file,data_buffer);
read(data_buffer,data_stimulus);
test_data_in <= signed(to_stdlogicvector(data_stimulus));
wait for 12 ns;
else
test_data_in <= (others => '0');
end if;
end if;
wait until rising_edge(clk); -- added for endfile
end process;
wr_process:
process
variable wr_buf: line;
variable wr_stimulus: bit_vector(n_in-1 downto 0);
begin
while not endfile(wr_file) loop
if test_start = '1' and test_rst = '1' then
readline(wr_file,wr_buf);
read(wr_buf,wr_stimulus);
test_wr_in <= signed(to_stdlogicvector(wr_stimulus));
wait for 20 ns;
end if;
end loop;
wait for 20 ns; -- added for when endfile(wr_file) is TRUE.
end process;
writing_process:
process
variable string_line: string(n_out downto 1);
variable out_line: line;
-- variable i: integer; -- the following are not my i
begin
wait for 12 ns;
while test_start = '1' and test_rst = '1' loop
for i in test_output'range loop -- n_out-1 downto 0 loop
if test_output(i) = '0' then
string_line(i + 1) := '0';
else
string_line(i + 1) := '1';
end if;
end loop;
write(out_line, string_line);
writeline(br_out, out_line);
wait until rising_edge(clk);
for i in test_output'range loop -- n_out-1 downto 0 loop
if test_output(i) = '0' then
string_line(i + 1) := '0';
else
string_line(i + 1) := '1';
end if;
end loop;
write(out_line,string_line);
writeline(bi_out,out_line);
wait until rising_edge(clk);
for i in test_output'range loop -- n_out-1 downto 0 loop
if test_output(i) = '0' then
string_line(i+1) := '0';
else
string_line(i+1) := '1';
end if;
end loop;
write(out_line,string_line);
writeline(ar_out,out_line);
wait until rising_edge(clk);
for i in test_output'range loop -- n_out-1 downto 0 loop
if test_output(i) = '0' then
string_line(i+1) := '0';
else
string_line(i+1) := '1';
end if;
end loop;
write(out_line,string_line);
writeline(ai_out,out_line);
end loop;
end process;
end architecture;
I added
wait until rising_edge(clk); -- added for endfile
before the end of the process in data_in_process, otherwise it would loop without suspending if END_FILE(br_in_file) is TRUE. (And you should really have a test or test that covers all your inputs).
I added
wait for 20 ns; -- added for when endfile(wr_file) is TRUE.
to wr_process for the same reason.
The changes to writing_process were used to discover a working range for the test_output signal. Note the the process declarative item for variable i can be removed, it's not used. (The i there is not the i in the loop constants).
I found the problems with the input files by in a UNIX environment (OS X) touching the input files which creates them with a zero length (after insuring my VHDL simulator would complain if they don't exist).

PS2 keyboard delay error / VHDL

I have a problem that is caused by this keyboard interface. I'm trying to make a digital piano with a keyboard and an amplifier but the sound does not come as we press the button; there is a ~1 second delay. Can you help me with this problem please? Also when we change the code part
Shift2_next <= Shift1(0) & Shift2(10 downto 1);
to
Shift2_next <= PS2Df & Shift2(10 downto 1);
the key gives the sound instantly as wanted but now the sound does not stop; the break code is corrupted in that case I think. Hope you can help. Thanks.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity keyboard_ctrl is
port(
clk25 : in STD_LOGIC;
PS2C : in STD_LOGIC;
PS2D : in STD_LOGIC;
xkey : out STD_LOGIC_VECTOR(16 downto 1)
);
end keyboard_ctrl;
architecture keyboard of keyboard_ctrl is
signal PS2Cf, PS2Df: std_logic;
signal PS2Cf_next, PS2Df_next: std_logic;
signal ps2c_filter, ps2d_filter: std_logic_vector(7 downto 0);
signal shift1,shift2: std_logic_vector(10 downto 0);
signal shift1_next,shift2_next: std_logic_vector(10 downto 0);
begin
xkey <= shift1(8 downto 1)&shift2(8 downto 1);
-- filter for PS2 clock and data
filter: process(clk25)
begin
if clk25'event and clk25 = '1' then
ps2c_filter(7) <= PS2C;
ps2c_filter(6 downto 0) <= ps2c_filter(7 downto 1);
ps2d_filter(7) <= PS2D;
ps2d_filter(6 downto 0) <= ps2d_filter(7 downto 1);
PS2Cf <= PS2Cf_next;
PS2Df <= PS2Df_next;
end if;
end process filter;
PS2Cf_next <= '1' when ps2c_filter = X"FF" else
'0' when ps2c_filter = X"00" else
PS2Cf;
PS2Df_next <= '1' when ps2d_filter = X"FF" else
'0' when ps2d_filter = X"00" else
PS2Df;
--Shift used to clock in scan codes from PS2--
shift: process(PS2Cf)
begin
if (PS2Cf'event and PS2Cf = '0') then
shift1 <= shift1_next;
shift2 <= shift2_next;
end if;
end process shift;
Shift1_next <= PS2Df & Shift1(10 downto 1);
Shift2_next <= Shift1(0) & Shift2(10 downto 1);
end keyboard;
You have to change the design to be synchronous specially when using PS2. I recommend you check the clock for the PS2 make sure it is attached to the 25 MHz pin or try use a higher frequency clock and divide it until you get the correct timing. Attached example of dividing a clock by 3, you can change it and use it
Best Wishes,
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity divide_by_3 is
port (
cout :out std_logic; -- Output clock
clk :in std_logic; -- Input clock
reset :in std_logic -- Input reset
);
end entity;
architecture rtl of divide_by_3 is
signal pos_cnt :std_logic_vector (1 downto 0);
signal neg_cnt :std_logic_vector (1 downto 0);
begin
process (clk, reset) begin
if (reset = '1') then
pos_cnt <= (others=>'0');
elsif (rising_edge(clk)) then
if (pos_cnt = 2) then
pos_cnt <= pos_cnt + 1;
end if;
end if;
end process;
process (clk, reset) begin
if (reset = '1') then
neg_cnt <= (others=>'0');
elsif (falling_edge(clk)) then
if (neg_cnt = 2) then
neg_cnt <= neg_cnt + 1;
end if;
end if;
end process;
cout <= '1' when ((pos_cnt /= 2) and (neg_cnt /= 2)) else
'0';
end architecture;
-------------------------------------------------------
-- Testbench to check the divide_by_3 logic
-------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_textio.all;
use std.textio.all;
entity div3_tb is
end entity;
architecture test of div3_tb is
signal cout :std_logic;
signal clk :std_logic := '1';
signal reset :std_logic := '1';
component divide_by_3 is
port (
cout :out std_logic;
clk :in std_logic;
reset :in std_logic
);
end component;
begin
-- Generate clock
clk <= not clk after 10 ns;
reset <= '0' after 20 ns;
Inst_div3 : divide_by_3
port map (
cout => cout, -- Output
clk => clk, -- Input
reset => reset -- Iinput
);
end architecture
;

ps/2 keyboard interface VHDL

Alright so I'm trying to implement a keyboard controller for use with an altera DE2 FPGA board, and am having some issues. I have ran this code in the quartus simulator and everything seems to be doing what I think it should be doing. However, when I try to program it onto the FPGA, nothing works. I have targeted it down to the way I'm simulating the ps/2 clock and the system clock doesn't appear to be how they are actually running.
I simulated the system clock at 50 mhz, 20ns period, and the ps2clock with a 90ns period. When setting the ps2data, to random values throughout the simulation, the correct bits are loaded into the 8 bit scan code. The problem is that when programmed to the board, the state machine never leaves the idle state. The state machine should leave the idle state on the falling edge of the ps2 clock when the data bit is zero, which seems to never happen. I have the ps2data and ps2clock pins connected to the correct inputs, but can't seem to figure out the problem.
I didn't add the top level entity that tests this, but it simply takes the output keyCode and sends it to one of the 7seg displays. I feel like the answer to this has something to do with the ps2clock, im just not sure what exactly.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity keyboard is
Port ( Clk : in std_logic; --system clock
ps2Clk : in std_logic; --keyboard clock
ps2Data : in std_logic; --keyboard data
reset : in std_logic; --system reset
keyReady : out std_logic;
DoRead : in std_logic; -- when to read
keyCode : out std_logic_vector(7 downto 0);
pFalling : out std_logic; --debugging
pFixedClk : out std_logic_vector(1 downto 0); --debugging
divClock_out : out std_logic; --debugging
clockCount_out : out std_logic_vector(9 downto 0); --debugging
testDiv_out : out std_logic;
bitCount_out : out std_logic_vector(3 downto 0);
shiftIn_out : out std_logic_vector(8 downto 0)); --debugging
end keyboard;
architecture Behavioral of keyboard is
component div_counter is
Port(clk, reset : in std_logic;
Q : out std_logic_vector(9 downto 0));
end component div_counter;
signal shiftIn : std_logic_vector(8 downto 0); -- shifted in data
signal ps2fixedClock : std_logic_vector(1 downto 0); -- 2 bit shift register
signal divClock : std_logic ; -- main clock/512
signal clockCount : std_logic_vector(9 downto 0); -- debugging
signal ps2falling : std_logic ;
signal bitCount : std_logic_vector(3 downto 0);
signal keyReady_sig : std_logic;
type state_type is (idle, shift, ready);
signal state : state_type;
begin
keyReady <= keyReady_sig;
-------------------------------
--- counter to divide the main clock by 512
-------------------------------
counter : div_counter
Port map(clk => Clk,
reset => reset,
Q => clockCount);
clockCount_out <= clockCount;
divided_clock : process (clockCount)
begin
if clockCount = "1000000001" then
divClock <= '1';
else
divClock <= '0';
end if;
end process divided_clock;
testDiv_out <= divClock;
------------------------------------
------ 2 bit shift register to sync clocks
------------------------------------
ps2fixed_Clock : process (reset, divClock)
begin
if reset = '1' then
ps2fixedClock <= "00";
elsif (divClock'event and divClock = '1') then
ps2fixedClock(0) <= ps2fixedClock(1);
ps2fixedClock(1) <= ps2Clk;
end if;
end process ps2fixed_Clock;
pFixedClk <= ps2fixedClock;
-----------------------------------
-------- edge detector
-----------------------------------
process (ps2fixedClock)
begin
if ps2fixedClock = "01" then
ps2falling <= '1';
else
ps2falling <= '0';
end if;
end process;
pFalling <= ps2falling;
bitCount_out <= bitCount;
--------------------------------
------- state machine
--------------------------------
state_machine : process (divClock, reset)
begin
if (reset = '1') then
state <= idle;
bitCount <= "0000";
shiftIn <= (others => '0');
keyCode <= (others => '0');
keyReady_sig <= '0';
elsif (divClock'event AND divClock = '1') then
if DoRead='1' then
keyReady_sig <= '0';
end if;
case state is
when idle =>
bitCount <= "0100";
if ps2falling = '1' and ps2Data = '0' then
state <= shift;
end if;
when shift =>
if bitCount >= 9 then
if ps2falling = '1' then -- stop bit
keyReady_sig <= '1';
keyCode <= shiftIn(7 downto 0);
state <= idle;
end if;
elsif ps2falling='1' then
bitCount <= bitCount + 1;
shiftIn(7 downto 0) <= shiftIn(8 downto 1);
shiftIn(8) <= ps2Data;
end if;
when others =>
state <= idle;
end case;
end if;
end process;
shiftIn_out <= shiftIn;
end Behavioral;
Coming back to answer this a bit later....
It turns out the reason why this wasn't working was because I was using a usb -> ps2 adapter and not an original ps2 connector keyboard.
you try to sync the ps2clock to your divClock. however, divClock is an enable signal and not a clock. it is active not very often.
I suggest that you use clk in ps2fixed_Clock process
ps2fixed_Clock : process (reset, clk)
begin
if reset = '1' then
ps2fixedClock <= "00";
elsif (rising_edge(clk)) then
ps2fixedClock(0) <= ps2fixedClock(1);
ps2fixedClock(1) <= ps2Clk;
end if;
end process ps2fixed_Clock;
also you should use clk in your state_machine process
state_machine : process (clk, reset)
begin
if (reset = '1') then
...
elsif (rising_edge(clk)) then
...
if you want to use a clock divider (divided_clock process), you can generate an enable signal (as you did) and use it after you synchronized the clocks, e.g. in the state machine!

VHDL - Making a clock from another module's output signal

I am modifying a simple keyboard interface I found on the net to my use. The idea is whenever there is a new scancode, it will make the output named "Scan_Dav" go high, and then go low. So when I direct Scan_Dav to another module as a clock, that module's clock will have a rising edge whenever a new ScanCode is pressed. Is there any error in my way of thinking? Because I tried it and directed the scancode and scan_dav to the rest of my project -which writes letters side by side with the given scancodes and shows them on seven segment display- the displayed text had 2 of each character ( i.e. when I write FLY the text was like FFLLYY). If there is no errors, I will share my code and ask you why it is not working. Thanks :)
EDIT: This is where the shifting is done according to values of 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;
This is where Scan_Dav comes from, the code is taken from here:
(You may ignore the filtering part)
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;
UPDATE: The only problem that remains is the delayed display and shifting of the letter and the text. While writing VHDL, I get nothing after pressing V, then I get V when I press H and it goes like that. The last letter does not appear until another key is pressed.It seems to be an issue about Scan_Dav, yet I can not resolve what it is. Any help will be appreciated.
Driving a clock input from logic output is generally bad practice (and some FPGA fabrics will not allow it at all). Clocks run best when sourced from dedicated clock logic inside the part, and good designs should minimize the number of clocks. Ideally you'd have only one, but that's not always possible.
Instead of running a clock input from logic, consider running everything off of one clock and use "enables" to activate the logic only when needed. In this case, you would detect the rising-edge transition of scan_dav inside of the downstream module and only react when that transition occurs. The detection logic would run off of the same clock as the scan_dav module.
I don't think this explains why you're seeing double characters, you would need to post some code to analyze. However, I would recommend that you re-tool to not drive clocks from logic.
If I see it right you avoid the F0 when you release the Key but you do not filter the second scancode.
It's always like this
Scancode --- press Key
F0 --- relesase Key
Scancode
on some Keys (e.g ALT GR) you can get an E0 too.
It not complete description but the most importand thinks are shown.
http://en.wikipedia.org/wiki/Scancode
This would lead to the descripted problem. FLY -> FFLLYY.

Resources