I emulated this VHDL code using GHDL in terminal, no errors occured, but when I imported .vcd file into GTKWAVE no signal shown up.
SCREENSHOT OF GTKWAVE
Desing Code:
Library ieee; Use ieee.std_logic_1164.all;
Use ieee.numeric_std.all;
entity EXO is
port (CLK, EN: in bit; SORTIE: out bit);
end entity;
architecture EXXO of EXO is
signal compt : integer range 0 to 7 ;
signal etat : bit;
begin
process (CLK)
begin
if CLK'event and CLK = '1' then
if EN = '1' then
compt <= compt + 1;
case etat is
when '0' => if compt = 3 then compt <= 0; SORTIE <= '1'; etat <= '1'; end if;
when '1' => if compt = 2 then compt <= 0; SORTIE <= '0'; etat <= '0'; end if;
end case;
end if;
end if;
end process;
end architecture;
EDIT: I am new to VHDL, so please bear with me.
I am required to complete this
chronogram. The design code is given. I tried to create a Test bench for it, and here is the result:
GTKWAVE Screenshot 2 Which is obviously an utter failure (Failed to show compt, etat, SORTIE).
Test Bench:
Library ieee; Use ieee.std_logic_1164.all;
Use ieee.numeric_std.all;
entity EXOtb is
end entity;
architecture EXXOtb of EXOtb is
component EXO
port (CLK, EN: in bit; SORTIE: out bit);
end component;
signal CLKtb, ENtb: bit;
signal SORTIEtb: bit;
begin
DUT: EXO port map (CLK => CLKtb, EN => ENtb, SORTIE => SORTIEtb );
STIMULUS: process
begin
CLKtb <= '0'; ENtb <= '0'; wait for 10 ns;
CLKtb <= '0'; ENtb <= '1'; wait for 10 ns;
CLKtb <= '1'; ENtb <= '1'; wait for 10 ns;
CLKtb <= '1'; ENtb <= '1'; wait for 10 ns;
assert false report "Reached End of test";
wait;
end process;
end architecture;
EDIT 3: Thanks to #user1155120's detailed answer, I believe I have solved the problem.
Instead of declaring CLK values manually, I have created a proper function for it.
For some reason, in order to show internal signals in GTKWAVE, You need to declare them as well in the test bench, honestly I don't know why.
By looking carefully into the design code, the input EN seems to refer to some enabling property, and the code runs only if EN is true, so in the test bench I gave it the value of 1. Also, that if EN = '1' then seems to be redundant and there is no need for since EN is always 1. I kept it as it is though.
The new Design Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity EX is
Port ( CLK : in STD_LOGIC;
EN : in STD_LOGIC;
SORTIE : out STD_LOGIC);
end EX;
architecture Behavioral of EX is
signal compt : integer range 0 to 7 ;
signal etat : bit;
begin -- Stimulus process
process (CLK)
begin
if CLK'event and CLK = '1' then
if EN = '1' then
compt <= compt + 1;
case etat is
when '0' => if compt = 3 then compt <= 0; SORTIE <= '1'; etat <= '1'; end if;
when '1' => if compt = 2 then compt <= 0; SORTIE <= '0'; etat <= '0'; end if;
end case;
end if;
end if;
end process;
end Behavioral;
Test Bench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY EXTB IS
END EXTB;
ARCHITECTURE behavior OF EXTB IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT EX
PORT(
CLK : IN std_logic;
EN : IN std_logic;
SORTIE : OUT std_logic
);
END COMPONENT;
--Inputs
signal CLK : std_logic := '0';
signal EN : std_logic := '1';
-- Inner
signal compt : integer range 0 to 7 ;
signal etat : bit;
--Outputs
signal SORTIE : std_logic;
-- Clock period definitions
constant CLK_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: EX PORT MAP (
CLK => CLK,
EN => EN,
SORTIE => SORTIE
);
-- Clock process definitions
CLK_process :process
begin
CLK <= '0';
wait for CLK_period/2;
CLK <= '1';
wait for CLK_period/2;
end process;
-- Stimulus process
process (CLK)
begin
if CLK'event and CLK = '1' then
if EN = '1' then
compt <= compt + 1;
case etat is
when '0' => if compt = 3 then compt <= 0; SORTIE <= '1'; etat <= '1'; end if;
when '1' => if compt = 2 then compt <= 0; SORTIE <= '0'; etat <= '0'; end if;
end case;
end if;
end if;
end process;
END;
GTKWAVE result (All signals are shown as required in the homework)
Related
I have created a bit sequence detector (for sequence 1110) using VHDL. I have used Moore’s State Machine to accomplish the task.
I am able to compile my code and get the desired output.
But on the FPGA board I am supposed to use SW0 as clock, SW1 as data input, SW2 as RESET, any of the LED as data output.
The problems I am facing:
I am unable to assign the clock signal to a switch, I always get an error. So I assigned the clock signal to the default clock signal on the board i.e. LOC = "E3" it work fine. But according to my question I need to assign it to a switch. How do do that?
I am unable to show the output on the fpga board i.e. the led lights up too fast for the naked eye once the data in pin is applied. Any suggestion on how to display the output using 3 input switch and an LED as output as per the above question?
The following code is my design implementation:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Design is
Port ( clock : in STD_LOGIC;
din : in STD_LOGIC;
rst : in STD_LOGIC;
dout : out STD_LOGIC);
end Design;
architecture Behavioral of Design is
type state is (st0, st1, st2, st3, st4);
signal present_state, next_state : state;
begin
synchronous_process: process (clock)
begin
if rising_edge(clock) then
if (rst = '1') then
present_state <= st0;
else
present_state <= next_state;
end if;
end if;
end process;
output_decoder : process(present_state, din)
begin
next_state <= st0;
case (present_state) is
when st0 =>
if (din = '1') then
next_state <= st1;
else
next_state <= st0;
end if;
when st1 =>
if (din = '1') then
next_state <= st2;
else
next_state <= st0;
end if;
when st2 =>
if (din = '1') then
next_state <= st3;
else
next_state <= st0;
end if;
when st3 =>
if (din = '1') then
next_state <= st3;
else
next_state <= st4;
end if;
when st4 =>
if (din = '1') then
next_state <= st1;
else
next_state <= st0;
end if;
when others =>
next_state <= st0;
end case;
end process;
next_state_decoder : process(present_state)
begin
case (present_state) is
when st0 =>
dout <= '0';
when st1 =>
dout <= '0';
when st2 =>
dout <= '0';
when st3 =>
dout <= '0';
when st4 =>
dout <= '1';
when others =>
dout <= '0';
end case;
end process;
end Behavioral;
The following is my testbench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_moore is
end tb_moore;
architecture Behavioral of tb_moore is
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT Design
PORT(
clock : IN std_logic;
din : IN std_logic;
rst : IN std_logic;
dout : OUT std_logic
);
END COMPONENT;
--Inputs
signal clock : std_logic := '0';
signal din : std_logic := '0';
signal rst : std_logic := '0';
--Outputs
signal dout : std_logic;
-- Clock period definitions
constant clk_period : time := 20 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: Design PORT MAP (
clock => clock,
din => din,
rst => rst,
dout => dout
);
-- Clock process definitions
clk_process :process
begin
clock <= '0';
wait for clk_period/2;
clock <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
rst <= '1';
wait for 20 ns;
rst <= '0';
din <= '1';
wait for 20 ns;
din <= '1';
wait for 20 ns;
din <= '1';
wait for 20 ns;
din <= '1';
wait for 20 ns;
din <= '1';
wait for 20 ns;
din <= '0';
wait for 20 ns;
din <= '1';
wait for 20 ns;
din <= '1';
end process;
END;
and the following is the constrains file i used for the Nexys DDR4 FPGA Board.
## Clock signal
NET "clock" LOC = "E3" | IOSTANDARD = "LVCMOS33";
## Switches
NET "din" LOC=L16 | IOSTANDARD=LVCMOS33;
NET "rst" LOC=M13 | IOSTANDARD=LVCMOS33;
## LEDs
NET "dout" LOC=H17 | IOSTANDARD=LVCMOS33;
I have been trying to make a generic sequence detector. When i try to simulate my design, I get a simulator 45-1 Fatal run time error. Can somebody please help me with this. Here is my Test bench and design.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Sequence_tb is
end Sequence_tb;
architecture Behavioral of Sequence_tb is
component sequence is
Generic(width: integer;
sequence: std_logic_vector);
Port(din,CLK,RST:in std_logic;
dout: out std_logic;
temp: buffer std_logic_vector(0 to width-1));
end component;
constant CLK_period: time := 10ns;
constant width: integer := 4;
constant sequence0: std_logic_vector(width-1 downto 0) := "1010";
signal din,CLK,RST,dout: std_logic := '0';
signal temp : std_logic_vector(0 to width-1) := (others=>'0');
begin
uut: sequence generic map(width=>width,sequence=>sequence0)
port map(din=>din,CLK=>CLK,RST=>RST,dout=>dout,temp=>temp);
CLK_proc: process
begin
CLK <= not CLK;
wait for CLK_period;
end process;
RST_proc: process
begin
RST <= '1';
wait for 20 ns;
RST <= '0';
wait;
end process;
din_proc: process
begin
din <= '1';
wait for 30 ns;
din <= '0';
wait for 10 ns;
din <= '1';
wait for 10 ns;
din <= '0';
wait for 10 ns;
din <= '1';
wait for 10 ns;
wait;
end process;
end Behavioral;
Design File:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Sequence is
Generic(width: integer;
sequence: std_logic_vector);
Port (din, CLK, rst: in std_logic;
dout: out std_logic;
temp: buffer std_logic_vector(0 to width-1));
end Sequence;
architecture Beh of Sequence is
subtype statetype is integer range 0 to width-1;
signal prstate,nxstate: statetype := 0;
begin
process(RST,CLK)
begin
if RST='1' then
temp <= (others => '0');
nxstate <= 0;
elsif CLK'event and CLK='1' then
temp(prstate) <= din;
for k in prstate downto 0 loop
if temp(k downto 0) = sequence(k downto 0) then
nxstate <= k;
exit;
else temp <= temp(1 to width-1) & '0';
end if;
end loop;
end if;
prstate <= nxstate;
end process;
dout <= '1' when prstate = width-1 and din = sequence(sequence'left) else '0';
end Beh;
I am a beginner in VHDL coding and I have some problem with my simple state machine. I just want this machine to change the output value loc_RL when the state changes. When I am simulating, there is no value (like 'U') for loc_RL.
Here is my code:
library ieee;
use ieee.std_logic_1164.all;
entity RL is
port (clk, reset, pon_RL, rtl_RL, ACDS_RL, LADS_RL, REN_RL, LLO_RL, MLA_RL, GTL_RL : in std_logic;
loc_RL : out std_logic);
end RL;
architecture behavioral of RL is
type STATE_TYPE is (LOCS, REMS, LWLS, RWLS);
signal state : STATE_TYPE;
begin
process(clk, reset)
begin
if reset='1' then
state <= LOCS;
elsif (rising_edge(clk)) then
case state is
when LOCS =>
if pon_RL = '1' then
state <= REMS;
else
state <= LOCS;
end if;
when REMS =>
if pon_RL = '1' then
state <= LWLS;
else
state <= REMS;
end if;
when LWLS =>
if pon_RL = '1' then
state <= RWLS;
else
state <= LWLS;
end if;
when RWLS =>
if pon_RL = '1' then
state <= LOCS;
else
state <= RWLS;
end if;
end case;
end if;
end process;
process(state)
begin
case state is
when LOCS =>
loc_RL <= '1';
when REMS =>
loc_RL <= '0';
when LWLS =>
loc_RL <= '1';
when RWLS =>
loc_RL <= '0';
end case;
end process;
end behavioral;
testbench:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity RL_tb is
end RL_tb;
architecture testbench of RL_tb is
component RL
port (clk, reset, pon_RL, rtl_RL, ACDS_RL, LADS_RL, REN_RL, LLO_RL, MLA_RL, GTL_RL : in std_logic;
loc_RL : out std_logic);
end component;
--wejscia
signal tclk : std_logic;
signal treset: std_logic;
signal tpon_RL : std_logic;
signal trtl_RL : std_logic;
signal tACDS_RL : std_logic;
signal tLADS_RL : std_logic;
signal tREN_RL : std_logic;
signal tLLO_RL : std_logic;
signal tMLA_RL : std_logic;
signal tGTL_RL : std_logic;
--wyjscia
signal loc_RL : std_logic;
--definicja zegara
constant clk_period : time := 40 ns;
begin
--inicjalizacja UUT
uut: RL port map (
tclk,
treset,
tpon_RL,
trtl_RL,
tACDS_RL,
tLADS_RL,
tREN_RL,
tLLO_RL,
tMLA_RL,
tGTL_RL
);
process
begin
tclk <= '0';
wait for clk_period/2;
tclk <= '1';
wait for clk_period/2;
end process;
process
begin
treset <= '1';
wait for 10 ns;
treset <= '0';
tpon_RL <= '1';
end process;
end;
It is compiling correctly, I can proceed to the simulation. I am using NCLaunch from Cadence. Thanks in advance for help.
Analyzing, elaborating and simulating your design and testbench gives:
And looking at the testbench shows:
architecture testbench of RL_tb is
component RL
port (
clk,
reset,
pon_RL,
rtl_RL,
ACDS_RL,
LADS_RL,
REN_RL,
LLO_RL,
MLA_RL,
GTL_RL: in std_logic;
loc_RL: out std_logic
);
end component;
--wejscia
signal tclk: std_logic;
signal treset: std_logic;
signal tpon_RL: std_logic;
signal trtl_RL: std_logic;
signal tACDS_RL: std_logic;
signal tLADS_RL: std_logic;
signal tREN_RL: std_logic;
signal tLLO_RL: std_logic;
signal tMLA_RL: std_logic;
signal tGTL_RL: std_logic;
--wyjscia
signal loc_RL: std_logic;
--definicja zegara
constant clk_period: time := 40 ns;
begin
--inicjalizacja UUT
uut:
RL
port map (
tclk,
treset,
tpon_RL,
trtl_RL,
tACDS_RL,
tLADS_RL,
tREN_RL,
tLLO_RL,
tMLA_RL,
tGTL_RL
);
process
begin
tclk <= '0';
wait for clk_period/2;
tclk <= '1';
wait for clk_period/2;
end process;
process
begin
treset <= '1';
wait for 10 ns;
treset <= '0';
tpon_RL <= '1';
end process;
end architecture;
No where is there an assignment to or initial value assigned to an input to the device under test other than clk, reset and tpon_RL.
Looking in the RL process we find that actual state branching out of LOCS depends on reset not being '1':
process (clk, reset)
begin
if reset = '1' then
state <= LOCS;
elsif (rising_edge(clk)) then
case state is
when LOCS =>
if pon_RL = '1' then
state <= REMS;
else
state <= LOCS;
end if;
when REMS =>
What's missing in your testbench stimulus is a release of the reset.
In the unlabeled process:
process
begin
treset <= '1';
wait for 10 ns;
treset <= '0';
tpon_RL <= '1';
end process;
You're missing a final wait statement:
process
begin
treset <= '1';
wait for 10 ns;
treset <= '0';
tpon_RL <= '1';
wait; -- added
end process;
Which prevents you from immediately assigning reset to a '1' again. Without suspension a process will loop, it's only suspending at the one wait statement, after setting reset to a '0' it's immediately setting it to a '1' before the process suspends, reset will only have a '1' value. No signal is updated while any process is active, there's only one projected output waveform value for any time, including the current simulation time. The assignment to a '1' overwrites the assignment to a '0'.
Fixing that gives:
And now we see the state machine is active.
I'm sending data to and A/D converter and I need the command data to be delayed at least 50ns from clk_19khz. Here is what I have so far.
How do I insert a delay of 50ns which is a requirement for the A/D between the clk_19khz and my first Dout bit to the A/D?
I'm using a Xilinx FPGA. Thanks for the help!
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity PSOL is
Port ( clk : in STD_LOGIC;
clk_19khz : OUT std_logic;
Dout :out std_logic);
end PSOL;
architecture Behavioral of PSOL is
signal temp : std_logic;
signal count : integer range 0 to 1301 := 0; --1301
signal temp2 : std_logic;
signal dcount : integer range 0 to 11 := 0; --
signal start : std_logic := '1'; -- indicates the start of
signal parity : std_logic := '1'; --used to varify data sent
signal stop : std_logic := '0'; --indicate when word/command has
--signal chip_select : bit :='1'; -- active low
begin
process (clk)
begin
if (clk' EVENT AND clk='1') then
if (count = 1301) then --1301
temp <= not(temp);
count <=0;
else
count <= count + 1;
end if;
end if;
end process;
clk_19khz <= temp;
temp2 <= temp;
process (temp2)
begin
If (temp2' EVENT and temp2 ='0') then
dcount <= dcount + 1;
parity <= '1';
stop <= '0';
start <='1';
if (dcount < 12 and start = '1' and stop = '0') then
CASE dcount is
when 1 => Dout <= start; -- need delay 50ns before this
when 2 => Dout <= '0';
when 3 => Dout <= '1';
when 4 => Dout <= '0';
when 5 => Dout <= '1';
when 6 => Dout <= '0';
when 7 => Dout <= '0';
when 8 => Dout <= '1';
when 9 => Dout <= '1';
when 10 => Dout <= parity;
when 11 => Dout <= '0';
when others => null;
end case;
end if;
end if;
--dcount <= 0;
--start <='1';
end process;
end Behavioral;
Your clock (50 MHz) has a period of 20 ns. So you'll need a modulo-3 counter to count a delay of at least 3 clock pulses which gives a delay of 60 ns.
Declarations:
signal delay_en : std_logic;
signal delay_us : unsigned(1 downto 0) := (others => '0');
signal delay_ov : std_logic;
Usage:
process(clk)
begin
if rising_edge(clk) then
if (delay_en = '1') then
delay_us <= delay_us + 1;
else
delay_us <= (others => '0');
end if;
end if;
end process;
delay_ov <= '1' when (delay_us = 2) else '0';
Your current implementation needs to drive delay_en while it's waiting for the timespan. If the delay is over, it emits the signal delay_ov (ov = overflow). This can be used by your solution to go on the in algorithm. Your code should also deassert delay_en, what clears the counter to 0.
I have written a vhdl code and I want to run it in FPGA, The code is working fine in ghdl and also in the Quartus 2 pre synthesis(RTL simulation) , but when i am running in gatelevel simulation, it is showing data_out as xxxxxxx .I cant able figure out what is the problem. Can anyone help me?
--- device code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity SimpleCalculator is
port ( data_in :in std_logic_vector(3 downto 0);
data_valid : in std_logic;
data_out : out std_logic_vector(7 downto 0);
clk, reset: in std_logic);
end entity SimpleCalculator;
architecture behave of SimpleCalculator is
----------------------------------
-- defining main state consisting of states of main thread
----------------------------------
type main_state is (main_idle,main_read0,main_read1,main_read2,main_read3,main_read4,main_calc);
signal next_mainstate: main_state;
-- below code creates two dimensional
-- array of 8 inputs with 16 bits each
type inputs_bit is array(0 to 4) of std_logic_vector(3 downto 0);
signal input_array : inputs_bit;
signal calc_start : std_logic;
signal calc_done : std_logic;
------------------------------
-- defining signals and states for calc thread
------------------------------
type calc_state is (calc_idle,calc_check_inputs,calc_running,calc_error);
signal calcstate : calc_state;
-----------------------------
begin
main: process(clk,reset,data_valid,next_mainstate,calc_done)
variable nstate:main_state;
--variable count: integer:=0;
begin
nstate := next_mainstate;
case next_mainstate is
when main_idle =>
if(data_valid = '1' ) then
nstate:= main_read0;
else
nstate:= main_idle;
end if;
when main_read0 =>
input_array(0) <= data_in;
nstate:=main_read1;
when main_read1 =>
input_array(1) <= data_in;
nstate:=main_read2;
when main_read2 =>
input_array(2) <= data_in;
nstate:=main_read3;
when main_read3 =>
input_array(3) <= data_in;
nstate:=main_read4;
when main_read4 =>
input_array(4) <= data_in;
nstate:=main_calc;
calc_start <= '1';
when main_calc =>
calc_start <= '0';
if(calc_done ='1') then
nstate:= main_idle;
else
nstate:=main_calc;
end if;
when others => null;
end case;
if(clk'event and clk = '1') then
if(reset = '1') then
next_mainstate <= main_idle;
else
next_mainstate <= nstate;
end if;
end if;
end process main;
------------------------------------------------
--calc fsm
---------------------------------------------
calc: process(clk,reset,calc_start,calcstate)
variable nstate:calc_state;
begin
nstate := calcstate;
case calcstate is
when calc_idle =>
if(calc_start = '1') then
nstate := calc_check_inputs;
else
nstate := calc_idle;
end if;
when calc_check_inputs =>
if(input_array(0) = "1010" and input_array(1) < "1010" and input_array(2) > "1011"
and input_array(3) < "1010" and input_array(4) = "1011") then
nstate := calc_running;
else
nstate := calc_error;
end if;
-- check for correct sequence
when calc_error =>
data_out <= "11111111";
when calc_running =>
case input_array(2) is
when "1100" =>
data_out <= std_logic_vector(unsigned(input_array(1)) * unsigned(input_array(3)) ) after 1 ns;
when "1101" =>
data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) + unsigned(input_array(3)) ) after 1 ns;
when "1110" =>
data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) - unsigned(input_array(3)) ) after 1 ns;
when "1111" =>
data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) / unsigned(input_array(3)) ) after 1 ns;
when others => null;
end case;
calc_done <='1';
nstate := calc_idle;
when others => null;
end case;
if(clk'event and clk = '1') then
if(reset = '1') then
calcstate <= calc_idle;
else
calcstate <= nstate;
end if;
end if;
end process calc;
end behave;
--- **testbench**
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library std;
use std.textio.all;
entity Simplecalculator_tb is
end entity;
architecture behave of Simplecalculator_tb is
signal data_in : std_logic_vector(3 downto 0);
signal data_valid : std_logic:= '0';
signal data_out : std_logic_vector(7 downto 0);
signal clk, reset: std_logic:= '0';
file stimulus_file: text is in "calci_inputs.txt";
file result_file: text is in "calci_result.txt";
component SimpleCalculator is
port ( data_in :in std_logic_vector(3 downto 0);
data_valid : in std_logic;
data_out : out std_logic_vector(7 downto 0);
clk, reset: in std_logic);
end component;
begin
-- 10 ns clock.
clk <= not clk after 5 ns;
process
variable L: line;
variable next_number_input: bit_vector(3 downto 0);
variable next_number_output: bit_vector(7 downto 0);
begin
reset <= '1';
data_valid <= '0';
wait until clk ='1';
reset <= '0';
data_valid <= '1';
wait until clk ='1';
data_valid <= '0';
while( not endfile(stimulus_file)) loop
readline(stimulus_file,L);
read(L,next_number_input);
data_in <= To_StdLogicVector(next_number_input);
wait until clk='1';
assert false report "Sent item " severity note;
end loop;
assert false report "Sent all items " severity note;
wait for 20 ns;
assert false report "Received done " severity note;
readline(result_file,L);
read(L,next_number_output);
if(data_out = To_StdLogicVector(next_number_output)) then
assert false report "SUCCESS: got the correct result." severity note;
else
assert false report "FAILURE: incorrect result! " severity ERROR;
end if;
wait;
end process;
dut : SimpleCalculator port map
( data_in => data_in, data_valid => data_valid, data_out => data_out, clk => clk,
reset => reset);
end behave;
---input file
1010
0111
1110
0010
1011
-- output file content
00000101
I have changed my code and the testbench and I have included the even the delays, but still I am getting the same xxxx error...Can anyone pls help me what is wrong in the code..what else I need to change.Thanks in advance
------ modified code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity SimpleCalculator is
port ( data_in :in std_logic_vector(3 downto 0);
data_valid : in std_logic;
data_out : out std_logic_vector(7 downto 0);
clk, reset: in std_logic);
end entity SimpleCalculator;
architecture behave of SimpleCalculator is
----------------------------------
-- defining main state consisting of states of main thread
----------------------------------
type main_state is (main_idle,main_read0,main_read1,main_read2,main_read3,main_read4,main_calc);
signal next_mainstate: main_state;
-- below code creates two dimensional
-- array of 8 inputs with 16 bits each
type inputs_bit is array(0 to 4) of std_logic_vector(3 downto 0);
signal input_array : inputs_bit;
signal calc_start : std_logic;
signal calc_done : std_logic;
------------------------------
-- defining signals and states for calc thread
------------------------------
type calc_state is (calc_idle,calc_check_inputs,calc_running,calc_error);
signal calcstate : calc_state;
-----------------------------
begin
main: process(clk,reset,data_valid,next_mainstate,calc_done)
variable nstate:main_state;
--variable count: integer:=0;
begin
nstate := next_mainstate;
case next_mainstate is
when main_idle =>
if(data_valid = '1' ) then
nstate:= main_read0;
else
nstate:= main_idle;
end if;
when main_read0 =>
input_array(0) <= data_in after 2 ns;
nstate:=main_read1;
when main_read1 =>
input_array(1) <= data_in after 2 ns;
nstate:=main_read2;
when main_read2 =>
input_array(2) <= data_in after 2 ns;
nstate:=main_read3;
when main_read3 =>
input_array(3) <= data_in after 2 ns;
nstate:=main_read4;
when main_read4 =>
input_array(4) <= data_in after 2 ns;
nstate:=main_calc;
calc_start <= '1' after 2 ns;
when main_calc =>
calc_start <= '0' after 2 ns;
if(calc_done ='1') then
nstate:= main_idle;
else
nstate:=main_calc;
end if;
when others => null;
end case;
if(clk'event and clk = '1') then
if(reset = '1') then
next_mainstate <= main_idle;
else
next_mainstate <= nstate;
end if;
end if;
end process main;
------------------------------------------------
--calc fsm
---------------------------------------------
calc: process(clk,reset,calc_start,calcstate)
variable nstate:calc_state;
begin
nstate := calcstate;
case calcstate is
when calc_idle =>
if(calc_start = '1') then
nstate := calc_check_inputs;
else
nstate := calc_idle;
end if;
when calc_check_inputs =>
if(input_array(0) = "1010" and input_array(1) < "1010" and input_array(2) > "1011"
and input_array(3) < "1010" and input_array(4) = "1011") then
nstate := calc_running;
else
nstate := calc_error;
end if;
-- check for correct sequence
when calc_error =>
data_out <= "11111111";
when calc_running =>
case input_array(2) is
when "1100" =>
data_out <= std_logic_vector(unsigned(input_array(1)) * unsigned(input_array(3)) ) after 1 ns;
when "1101" =>
data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) + unsigned(input_array(3)) ) after 1 ns;
when "1110" =>
data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) - unsigned(input_array(3)) ) after 1 ns;
when "1111" =>
data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) / unsigned(input_array(3)) ) after 1 ns;
when others => null;
end case;
calc_done <='1' after 2 ns;
nstate := calc_idle;
when others => null;
end case;
if(clk'event and clk = '1') then
if(reset = '1') then
calcstate <= calc_idle;
else
calcstate <= nstate;
end if;
end if;
end process calc;
end behave;
-- new testbench
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library std;
use std.textio.all;
entity Simplecalculator_tb is
end entity;
architecture behave of Simplecalculator_tb is
signal data_in : std_logic_vector(3 downto 0):= (others => '0');
signal data_valid : std_logic:= '0';
signal data_out : std_logic_vector(7 downto 0);
signal clk, reset: std_logic:= '0';
file stimulus_file: text is in "/home/student/pavanpalla/lab_5/calci_inputs.txt";
file result_file: text is in "/home/student/pavanpalla/lab_5/calci_result.txt";
component SimpleCalculator is
port ( data_in :in std_logic_vector(3 downto 0);
data_valid : in std_logic;
data_out : out std_logic_vector(7 downto 0);
clk, reset: in std_logic);
end component;
begin
-- 10 ns clock.
clk <= not clk after 20 ns;
process
variable L: line;
variable next_number_input: bit_vector(3 downto 0);
variable next_number_output: bit_vector(7 downto 0);
begin
reset <= '1';
data_valid <= '0';
wait until clk ='1';
reset <= '0' after 2 ns;
data_valid <= '1' after 2 ns;
wait until clk ='1';
data_valid <= '0' after 2 ns;
while( not endfile(stimulus_file)) loop
readline(stimulus_file,L);
read(L,next_number_input);
data_in <= To_StdLogicVector(next_number_input) after 10 ns;
wait until clk='1';
assert false report "Sent item " severity note;
end loop;
assert false report "Sent all items " severity note;
wait for 50 ns;
assert false report "Received done " severity note;
readline(result_file,L);
read(L,next_number_output);
if(data_out = To_StdLogicVector(next_number_output)) then
assert false report "SUCCESS: got the correct result." severity note;
else
assert false report "FAILURE: incorrect result! " severity ERROR;
end if;
wait;
end process;
dut : SimpleCalculator port map
( data_in => data_in, data_valid => data_valid, data_out => data_out, clk => clk,
reset => reset);
end behave;
I am also attaching the images of presynthesis and postsynthesis. I cant able to figure out where I am giving wrong
presynthesis
post_synthesis
Gate-level simulation includes timing for design primitives, for example flip-flops, so setup and hold time for data to flip-flops must be respected, and otherwise the flip-flops may generate 'X' on the output.
The test bench code is not written with this in mind; for example:
wait until clk ='1';
reset <= '0';
The reset is removed 0 ps after rising edge of clk, and depending on the implementation there may be hold-time requirement for the synchronous design reset.
This can be addressed by running at a "slow" clock and only change data "far" from the rising clk edge. This is acceptable since design timing should be verified through Static Timing Analysis (STA) and not simulation; post-synthesis simulation is only to get a good feeling that the design is OK, but it is unrealistic to verify design timing through test cases.
You may also consider writing the processes as either clocked process or combinatorial process, since this generally will make design easier to write, read, and debug. The calc process is an example of a process both updating on rising edge of clk and on calcstate.