Simple VHDL 4 to 1 MUX testbench is hanging - vhdl

-----------begin part1.vhdl---------------------
library ieee;
use ieee.std_logic_1164.all;
entity part1 is
generic ( width : integer :=7);
PORT( a, b, c, d: IN std_logic_vector(width downto 0);
sel: IN std_logic_vector(1 downto 0);
result: OUT std_logic_vector(width downto 0)
);
end part1;
architecture muxbehav of part1 is
BEGIN
result <= a after 5 ns when sel="00" else
b after 5 ns when sel="01" else
c after 5 ns when sel="10" else
d after 5 ns;
end muxbehav;
-----------end part1.vhdl---------------------
-----------begin part1_tb.vhdl------------------
library ieee;
use ieee.std_logic_1164.all;
entity part1_tb is
generic( width : integer := 7);
end part1_tb;
architecture tb of part1_tb is
signal t_a: std_logic_vector(width downto 0):="00000000";
signal t_b: std_logic_vector(width downto 0):="00000000";
signal t_c: std_logic_vector(width downto 0):="00000000";
signal t_d: std_logic_vector(width downto 0):="00000000";
signal t_s: std_logic_vector(1 downto 0);
signal t_o: std_logic_vector(width downto 0);
component part1
generic(width : integer);
PORT( a, b, c, d: IN std_logic_vector(width downto 0);
sel: IN std_logic_vector(1 downto 0);
result: OUT std_logic_vector(width downto 0)
);
end component;
begin
U_part1: part1 generic map(width) port map(a=>t_a, b=>t_b, c=>t_c, d=>t_d, sel=>t_s, result=>t_o);
process
begin
t_a <= "11111111";
t_b <= "00000001";
t_c <= "10101010";
t_d <= "01010101";
wait for 10 ns;
t_s <= "00";
wait for 6 ns;
assert (t_o="11111111") report "Error input a" severity error;
wait for 10 ns;
t_s <= "01";
wait for 6 ns;
assert (t_o="00000001") report "Error input b" severity error;
wait for 10 ns;
t_s <= "10";
wait for 6 ns;
assert (t_o="10101010") report "Error input c" severity error;
wait for 10 ns;
t_s <= "11";
wait for 6 ns;
assert (t_o="01010101") report "Error input d" severity error;
wait;
end process;
end tb;
-----------end part1_tb.vhdl------------------
Hello, this is my first code I've written in VHDL. It's a simple 4 to 1 MUX that can take in a vector of any width. However, when I try running my testbench, GHDL just hangs. I've looked at testbenches similar to mine, but I still cannot find why mine is hanging. Any ideas?

Hmmm. I can't see any reason for it to hang.
I just tried your code in ghdl0.29 on Ubuntu 10.04 - works fine for me (in that it exits without printing any messages, so it seems your code works :) The waves look convincing in gtkwave also.
Can you try deleting your work folder and the executable and recompile?
Sorry, that's not really an answer that gets you forward!

Related

4-bit comparator issue in vhdl

I am new to VHDL and I have an issue writing a 4-bit comparator.
When I want to compare different sets of inputs there is only one output for all of them. And I don't know how to solve this problem. I want to have only one output and need to show 0000 if A is less than B, and 1111 if A is greater than B, and 0011 if they are equal. Can anybody please help me with my problem?
Here is my code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity comp_4 is
port ( A:IN STD_LOGIC_VECTOR(3 downto 0);
B:IN STD_LOGIC_VECTOR(3 downto 0);
output:OUT STD_LOGIC_VECTOR(3 downto 0)
);
end comp_4;
architecture dataflow of comp_4 is
begin
process
begin
if (A=B) then
output <= "0011";
elsif (A>B) then
output <= "1111";
else
output <= "0000";
end if;
wait;
end process;
end dataflow;
And also my test bench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY Comparator_test IS
END Comparator_test;
ARCHITECTURE Ctest OF Comparator_test IS
COMPONENT comp_4 IS
port( A:IN STD_LOGIC_VECTOR(3 downto 0);
B:IN STD_LOGIC_VECTOR(3 downto 0);
output:OUT STD_LOGIC_VECTOR(3 downto 0)
);
END COMPONENT;
SIGNAL a : STD_LOGIC_VECTOR(3 downto 0);
SIGNAL b : STD_LOGIC_VECTOR(3 downto 0);
SIGNAL c : STD_LOGIC_VECTOR(3 downto 0);
BEGIN
uut : comp_4 PORT MAP(a, b , c);
a <= "0100" , "1111" After 10 NS;
b <= "0101" , "1100" AFTER 10 NS;
END Ctest;
And my simulation looks like this:
You need to put the inputs on the sensitivity list.
Note, wait; stops the process infinitely (only in simulation, it cannot be synthesized).
Solution 1:
Use the process' sensitivity list, and remove wait;.
architecture dataflow of comp_4 is
begin
process(A, B)
begin
if (A = B) then
output <= "0011";
elsif (A > B) then
output <= "1111";
else
output <= "0000";
end if;
end process;
end dataflow;
Solution 2:
Use the sensitivity list of wait.
architecture dataflow of comp_4 is
begin
process
begin
if (A = B) then
output <= "0011";
elsif (A > B) then
output <= "1111";
else
output <= "0000";
end if;
wait on A, B;
end process;
end dataflow;

VHDL Shift Register

I am refreshing my VHDL programming skills (by using ModelSim), I wrote a Shift register project.
There is a problem, that I can't understand what should I do.
The problem is Q_out<=ACC; :when I wrote Q_out<=ACC inside the process, the data passed to Q_out at when the clk is going down, When i wrote Q_out<=ACC; after the process ended - Q_out changed when the clk is going up (as it meant to be) but at my test bench I see X instead of '1'...
what did I do wrong?
VHDL CODE:
Library ieee;
Use ieee.std_logic_1164.all;
Use work.New_Data_Pack.all;
Entity Shift_Reg IS
port(
Rst,Clk :IN std_logic;
Data :IN byte; -- std_logic_vector(7 downto 0);
Sel :IN t_shift; --sample, shl, shr, rotl, rotr
Q_out :OUT byte
);
End Shift_Reg;
ARCHITECTURE Shift_Reg_arc OF Shift_Reg IS
Signal ACC: byte:=(OTHERS=>'0'); -- std_logic_vector(7 downto 0);
BEGIN
ShiftPro:PROCESS (Rst,Clk)
BEGIN
IF Rst='1' Then
Q_out<=(OTHERS=>'0');
ACC<=(OTHERS=>'0');
ELSIF Clk'EVENT and Clk='1' THEN
CASE Sel is
WHEN sample=>
ACC<=Data;
WHEN shl=>
ACC<= ACC (6 downto 0) & '0'; -- & concatenation
WHEN shr=>
ACC<='0' & ACC (7 downto 1);
WHEN rotl=>
ACC<=ACC (6 downto 0)& ACC(7);
WHEN rotr=>
ACC<=ACC(0) & ACC(7 downto 1);
WHEN OTHERS=>
NULL;
END CASE;
END IF;
--Q_out<=ACC;
End PROCESS;
Q_out<=ACC;
End Shift_Reg_arc;
Test Bench:
Library ieee;
use ieee.std_logic_1164.all;
Use work.New_Data_Pack.all;
ENTITY Shift_Reg_TB IS END;
ARCHITECTURE Shift_Reg_TB_arc OF Shift_Reg_TB IS
---DUT Componenet Declaration
COMPONENT Shift_Reg
port(
Rst,Clk :IN std_logic;
Data :IN byte; -- std_logic_vector(7 downto 0);
Sel :IN t_shift; --sample, shl, shr, rotl, rotr
Q_out :OUT byte);
END COMPONENT;
-----Signal Declaration----
SIGNAL S_Clk,S_Rst :std_logic:='0';
SIGNAL S_Data, S_Q_out : byte;
SIGNAL S_Sel : t_shift;
SIGNAL S_Run :std_logic:='1';
BEGIN
-----DUT installation----
DUT: Shift_Reg
Port Map(S_Rst, S_Clk, S_Data, S_Sel, S_Q_out);
-----Signal Wave Creation----
S_Rst<='1' after 0ns, '0' after 80 ns;
S_Run<= '1' after 0ns, '0' after 600 ns;
S_Sel<= sample, shl after 150 ns, shr after 250 ns,sample after 350 ns, rotl after 450 ns, rotr after 550 ns;
S_Data<=X"45" after 0ns;--, "10" after 125 ns, "33" after 620 ns, x"44" after 720 ns;
---CLK Creation---------
S_Clk_Create:Process
BEGIN
while S_Run='1' loop
S_clk<='1', '0' after 50 ns;
Wait for 100 ns;
END LOOP;
S_clk<='1';
Wait;
END PROCESS;
END Shift_Reg_TB_arc;
You have conflicting drivers for Q_out. Either it must be driven sequentially by the process, or it is driven concurrently and can never be driven by the process. But right now you have both a concurrent assignment outside the process:
Q_out<=ACC;
and a sequential assignment inside the process
IF Rst='1' Then
Q_out<=(OTHERS=>'0');
You must delete the in-process reset when you move the clocked update outside the process.

VHDL testbench not changing output ALU 32bit

You see, I've already finished to describe an ALU on vhdl with modelsim, however the testbench seems to not update the solution, when I see the simulation the circuit 32 bit response always says "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" I dont know what did i wrote wrong on the testbench also there is a warning on the compiler about the circuit response which says
** Warning: (vsim-8683) Uninitialized out port /alu_tb/ALU_test/res(32 downto 0) has no driver.
This port will contribute value (UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU) to the signal network.
and here is the testbench code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity ALU_tb is
end ALU_tb;
architecture bhv_ALU_tb of ALU_tb is
component ALU
port(
a, b: in std_logic_vector(31 downto 0);
c: in std_logic;
s: in std_logic_vector(3 downto 0);
res: out std_logic_vector(32 downto 0));
end component;
signal a, b: std_logic_vector(31 downto 0);
signal c: std_logic;
signal s: std_logic_vector(3 downto 0);
signal re: std_logic_vector(32 downto 0);
begin
ALU_test: ALU port map (a => a, b => b, c => c, s => s, res => re);
process begin
b <= "00000000000010100111010100011110";
a <= "00000000011010000100110011101110";
c <= '0';
s <= "1111";
wait for 2 ns;
b <= "00000000000010100111010100011110";
a <= "00000000011010000100110011101110";
c <= '0';
s <= "0100";
wait for 2 ns;
s <= "0000";
wait for 2 ns;
s <= "0001";
wait for 2 ns;
s <= "0010";
wait for 2 ns;
s <= "0011";
wait for 2 ns;
s <= "0100";
wait for 2 ns;
s <= "0101";
wait for 2 ns;
s <= "0110";
wait for 2 ns;
s <= "0111";
wait for 2 ns;
s <= "1000";
wait for 2 ns;
s <= "1001";
wait for 2 ns;
s <= "1010";
wait for 2 ns;
s <= "1011";
wait for 2 ns;
s <= "1100";
wait for 2 ns;
s <= "1101";
wait for 2 ns;
s <= "1110";
wait for 2 ns;
s <= "1111";
wait for 2 ns;
end process;
end bhv_ALU_tb;
i know the mistake seems trivial "res isn't initialized" but I've been away from vhdl way too long and honestly dont know how to fix it, any ideas?
Firstly
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
Bad.. don't use. You don't even need them in this file.
If you ever need arithmentic, use numeric_std.
Then: the error is in the component ALU, becasue that should 'drive' res. But since you did not post the code of that, we cannot help you (yet).
p.s. currently you do not need to define a component in VHDL anymore. You could just write:
ALU_test: entity work.ALU port map

test bench of a 32x8 register file VHDL

I wrote the assembly code for this circuit in vhdl already. I want to simulate it with a test bench.
RegWrite: 1 bit input (clock)
Write Register Number: 3-bit input(write addresses)
Write Data: 32-bit input (data in) Read
Register Number A: 3-bit input (read addresses)
Read Register Number B: 3-bit input (read adddresses)
Port A: 32-bit output (data out)
Port B: 32-bit output (data out)
I think my problem is that I don't understand what this circuit does. I chose random values to assign to the inputs, but it didn't output anything. What are good inputs to choose for this circuit?
here is my test bench file for reference:
library ieee;
use ieee.std_logic_1164.all;
entity Reg_TB is -- entity declaration
end Reg_TB;
architecture TB of Reg_TB is
component RegisterFile_32x8
port ( RegWrite: in std_logic;
WriteRegNum: in std_logic_vector(2 downto 0);
WriteData: in std_logic_vector(31 downto 0);
ReadRegNumA: in std_logic_vector(2 downto 0);
ReadRegNumB: in std_logic_vector(2 downto 0);
PortA: out std_logic_vector(31 downto 0);
PortB: out std_logic_vector(31 downto 0)
);
end component;
signal T_RegWrite : std_logic;
signal T_WriteRegNum: std_logic_vector(2 downto 0);
signal T_WriteData: std_logic_vector(31 downto 0);
signal T_ReadRegNumA: std_logic_vector(2 downto 0);
signal T_ReadRegNumB: std_logic_vector(2 downto 0);
signal T_PortA : std_logic_vector(31 downto 0);
signal T_PortB : std_logic_vector(31 downto 0);
begin
T_WriteRegNum <= "011";
T_WriteData <= "00000000000000000000000000000001";
T_ReadRegNumA <= "001";
T_ReadRegNumB <= "100";
U_RegFile: RegisterFile_32x8 port map
(T_RegWrite, T_WriteRegNum, T_WriteData,T_ReadRegNumA, T_ReadRegNumB, T_PortA, T_PortB);
-- concurrent process to offer clock signal
process
begin
T_RegWrite <= '0';
wait for 5 ns;
T_RegWrite <= '1';
wait for 5 ns;
end process;
process
begin
wait for 12 ns;
-- case 2
wait for 28 ns;
-- case 3
wait for 2 ns;
-- case 4
wait for 10 ns;
-- case 5
wait for 20 ns;
wait;
end process;
end TB;
as you can see I chose
WriteRegNum = "011"
WriteData = "00000000000000000000000000000001"
ReadRegNumA = "001"
ReadRegNumB = "100"
I think that I chose bad inputs. The simulation does this:
In general reading an address before it is written doesn't produce any useful results.
Your block diagram shows a 32 bit wide 8 word deep register file with two read ports and one write port with RegWrite used as a clock gated by the decode of the write address. A stable WriteRegNum value and a rising edge on RegWrite effects a write to the address specified by WriteRegNum.
The two read ports appear completely independent. Specifying an address on the respective ReadRegNumA or ReadRegNumB should output the contents of that register to the respective output port.
To get something useful out, you have to write to that location first, otherwise it will be the default value ((others => 'U'),) suspiciously like your waveform.
Trying writing to a location before expecting valid read data from it. Use values that are distinguishable by register location. Theoretically you should be preserving set up and hold time on WriteRegNum with respect to the rising edge of RegWrite.
Example stimulus producing output:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity registerfile_32x8 is
port (
RegWrite: in std_logic;
WriteRegNum: in std_logic_vector (2 downto 0);
WriteData: in std_logic_vector (31 downto 0);
ReadRegNumA: in std_logic_vector (2 downto 0);
ReadRegNumB: in std_logic_vector (2 downto 0);
PortA: out std_logic_vector (31 downto 0);
PortB: out std_logic_vector (31 downto 0)
);
end entity;
architecture fum of registerfile_32x8 is
type reg_array is array (0 to 7) of std_logic_vector(31 downto 0);
signal reg_file: reg_array;
begin
process(RegWrite)
begin
if rising_edge(RegWrite) then
reg_file(to_integer(unsigned(WriteRegNum))) <= WriteData;
end if;
end process;
PortA <= reg_file(to_integer(unsigned(ReadRegNumA)));
PortB <= reg_file(to_integer(unsigned(ReadRegNumB)));
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity reg_tb is
end entity;
architecture fum of reg_tb is
component registerfile_32x8
port (
RegWrite: in std_logic;
WriteRegNum: in std_logic_vector (2 downto 0);
WriteData: in std_logic_vector (31 downto 0);
ReadRegNumA: in std_logic_vector (2 downto 0);
ReadRegNumB: in std_logic_vector (2 downto 0);
PortA: out std_logic_vector (31 downto 0);
PortB: out std_logic_vector (31 downto 0)
);
end component;
signal RegWrite: std_logic := '1';
signal WriteRegNum: std_logic_vector (2 downto 0) := "000";
signal WriteData: std_logic_vector (31 downto 0) := (others => '0');
signal ReadRegNumA: std_logic_vector (2 downto 0) := "000";
signal ReadRegNumB: std_logic_vector (2 downto 0) := "000";
signal PortA: std_logic_vector (31 downto 0);
signal PortB: std_logic_vector (31 downto 0);
begin
DUT:
registerfile_32x8
port map (
RegWrite => RegWrite,
WriteRegNum => WriteRegNum,
WriteData => WriteData,
ReadRegNumA => ReadRegNumA,
ReadRegNumB => ReadRegNumB,
PortA => PortA,
PortB => PortB
);
STIMULUS:
process
begin
wait for 20 ns;
RegWrite <= '0';
wait for 20 ns;
RegWrite <= '1';
wait for 20 ns;
WriteData <= x"feedface";
WriteRegnum <= "001";
RegWrite <= '0';
wait for 20 ns;
RegWrite <= '1';
ReadRegNumA <= "001";
wait for 20 ns;
WriteData <= x"deadbeef";
WriteRegNum <= "010";
ReadRegNumB <= "010";
RegWrite <= '0';
wait for 20 ns;
RegWrite <= '1';
wait for 20 ns;
wait for 20 ns;
wait;
end process;
end architecture;
david_koontz#Macbook: ghdl -a regfile_32x8.vhdl
david_koontz#Macbook: ghdl -e reg_tb
david_koontz#Macbook: ghdl -r reg_tb --wave=reg_tb.ghw
david_koontz#Macbook: open reg_tb.gtkw
Essentially, the point is to have non 'U' values in a register file that's being read. If you notice the last write to WriteRegNum = "010", PortB shows undefined output until the write occurs.

VHDL coding in Isim Wave Window

In the Isim wave window my internal signals and outputs appear green and as initialized but all of my inputs appear as "UU" even though they are initialized as well. I am simply trying to add 1 whenever either of the two inputs are 1. The code synthesizes fine without warnings.
Any ideas?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity scoreboard2 is
Port ( clk : in STD_LOGIC;
T1 : in STD_LOGIC;
T2 : in STD_LOGIC;
Output : out STD_LOGIC_VECTOR (3 downto 0));
end scoreboard2;
architecture Behavioral of scoreboard2 is
signal output_temp: STD_LOGIC_VECTOR(3 downto 0) := "0000";
signal score1,score2: unsigned(1 downto 0) := "00";
signal score3: unsigned(3 downto 0):= "0000";
begin
proc: process(T1,T2,clk)
begin
if(rising_edge(clk)) then
if(T1 = '1') then
score1 <= score1 + 1;
end if;
if(T2 = '1') then
score2 <= score2 + 1;
end if;
end if;
end process proc;
score3 <= score1 & score2;
output_temp <= STD_LOGIC_VECTOR(score3);
Output <= output_temp;
end Behavioral;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY test6 IS
END test6;
ARCHITECTURE behavior OF test6 IS
COMPONENT scoreboard2
PORT(
clk : IN std_logic;
T1 : IN std_logic;
T2 : IN std_logic;
Output : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal clk : std_logic := '1';
signal T1 : std_logic := '1';
signal T2 : std_logic := '1';
--Outputs
signal Output : std_logic_vector(3 downto 0) := "0000";
signal output_temp: STD_LOGIC_VECTOR(3 downto 0) := "0000";
signal score1,score2: unsigned(1 downto 0) := "00";
signal score3: unsigned(3 downto 0):= "0000";
constant clk_period : time := 10 ns;
BEGIN
uut: scoreboard2 PORT MAP (
clk => clk,
T1 => T1,
T2 => T2,
Output => Output
);
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
stim_proc: process
begin
wait for 100 ns;
T1 <= '1';
wait;
end process;
END;
I don't have Isim but some simulators allow you to run a top level design with a port having unconnected inputs. It's usually synonymous with the ability to do interactive simulation (run, stop, step, force inputs, etc.).
Chapter 5 of ise_tutorial_ug695.pdf, March 1, 2011 (v13.1) says you need a test bench, i don't have all the documentation to determine whether that is enforced or not.
For a test bench:
library ieee;
use ieee.std_logic_1164.all;
entity scoreboard_tb is
end entity;
architecture test of scoreboard_tb is
signal clk: std_logic := '0';
signal T1: std_logic := '0';
signal T2: std_logic := '0';
signal RESULT: std_logic_vector(3 downto 0);
begin
UNDER_TEST:
entity work.scoreboard2
port map (
clk => clk,
T1 => T1,
T2 => T2,
Output => RESULT
);
CLOCK:
process
begin
if Now > 340 ns then -- simulation stops with no signal events
wait;
end if;
clk <= not clk;
wait for 20 ns;
end process;
STIMULUS:
process
begin
wait for 40 ns;
T1 <= '1';
wait for 40 ns;
T2 <= '1';
wait for 40 ns;
T1 <= '0';
T2 <= '0';
wait for 40 ns;
T2 <= '1';
wait for 40 ns;
T2 <= '0';
T1 <= '1';
wait for 40 ns;
T1 <= '0';
wait;
end process;
end architecture;
ghdl produces:
for you're scoreboard2 entity/architecture pair analyzed unchanged.
I don't have Isim either. Probably the softwave itself didn't work well. If there is a wave editor or something similar in Isim, use it instead of a testbench. Then simulate your project again. Hope this helps:)

Resources