0

I want to use four push buttons as inputs and three seven-segment LED displays as outputs. Two push buttons should step up and down through the sixteen RAM locations; the other two should increment and decrement the contents of the currently-displayed memory location. I am now trying to simulate my design using ModelSim test benches, with button presses. Here is what I believe to be the relevant portions of my code:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity DE2_TOP is

  port (
    KEY : in std_logic_vector(3 downto 0);         -- Push button
    );

end DE2_TOP;

architecture datapath of DE2_TOP is

begin  
  U1: entity work.lab1 port map (
    key => key,         
  );

end datapath;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity raminfr is                     -STANDARD RAM INFERENCE
    port (
        clk : in std_logic;
        we : in std_logic;
        a : in unsigned(3 downto 0);
        di : in unsigned(7 downto 0);
        do : out unsigned(7 downto 0)
    );
end raminfr;

architecture rtl of raminfr is

type ram_type is array (0 to 15) of unsigned(7 downto 0);
signal RAM : ram_type;
signal read_a : unsigned(3 downto 0);
begin
process (clk)
begin
    if rising_edge(clk) then
        if we = '1' then
            RAM(to_integer(a)) <= di;
        end if;
        read_a <= a;
    end if;
end process;
do <= RAM(to_integer(read_a));
end rtl;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity lab1 is
    port(
        clock : in std_logic;
        key : in std_logic_vector(3 downto 0); 
        );
end lab1;

architecture up_and_down of lab1 is
    signal value_in_ram : unsigned(7 downto 0);
    signal clk : std_logic;
    signal we : std_logic;
    signal value_counter    : unsigned(7 downto 0) ;
    signal register_counter : unsigned(3 downto 0);
        begin
    U1: entity work.raminfr port map (
        a   => register_counter,
        di  => value_counter,
        do  => value_in_ram,
        clk => clk,
        we  => we
    );

    process(clock)
        begin
            if rising_edge(clock) then
                if (key(3)='0' and key(2)='0' and key(1)='1' and key(0)='0') then
                    value_counter <= value_counter + "1";   
                elsif (key(3)='0' and key(2)='0' and key(1)='0' and key(0)='1') then  
                    value_counter <= value_counter - "1";   
                elsif (key(3)='1' and key(2)='0' and key(1)='0' and key(0)='0') then
                    register_counter<= register_counter + "1";
                    value_counter <= value_in_ram;
                elsif (key(3)='0' and key(2)='1' and key(1)='0' and key(0)='0') then
                    register_counter<= register_counter - "1";
                    value_counter <= value_in_ram;
                end if;
            end if;
    end process;
end architecture up_and_down;

The problem is that despite initializing "key" (the buttons) in my test bench, ModelSim still lists the object as "UUUU". Here is the code for my test bench, which is located in a separate file:

library ieee;
use ieee.std_logic_1164.all;

entity DE2_TOP_TEST is
end;

architecture BENCH of DE2_TOP_TEST is
signal KEY : std_logic_vector(3 downto 0);

begin
    KEY<="0010";
    U1: entity work.DE2_TOP port map (
        key=>key,
    );
end BENCH;

Anyone know what's wrong?

John Roberts
  • 5,885
  • 21
  • 70
  • 124
  • Make a testbench in VHDL would help a lot debugging your desing. In the testbench, you're emulating the behaviour of the outside world (most of the time: everything outside the FPGA/ASIC'. The testbench itself is only part of the simulation, not the implementation with ISE/Quartus/... In the testbench, you're pushing the buttons not inside the design itself. – vermaete Jan 26 '13 at 18:43
  • quick and dirty: move the 'key <= "..."' outside the process. Make it a concurrent assignment. And fix the sensitivity list of the process. Only the 'clock' should be there. – vermaete Jan 26 '13 at 18:46
  • I moved the key assignment immediately above the process statement, but I get the same result. Perhaps this is because ModelSim is pulling key from my DE2_TOP entity, where it would still be uninitialized since I've commented out the port mapping from lab1. I also have already made a test bench, but perhaps I'm not using it to its full advantage. Could you elaborate on this? – John Roberts Jan 26 '13 at 18:55
  • 1
    About testbenches: Doulos has made a good primer about it http://www.doulos.com/knowhow/vhdl_designers_guide/test_benches_part_1/ – vermaete Jan 26 '13 at 19:06
  • If you have a testbench, note that you have to simulate the testbench (vsim work._the_testbench_entity) i.s.o. the toplevel of you're design. I would go for the testbench and don't assert a value to 'key' within the design itself. Sorry for not reading all you;re code, I'm missing the time right now. – vermaete Jan 26 '13 at 19:08
  • I have a test bench, but I don't think I'm using it right. All I did was set it up through the GUI and point it to my D2_TOP file, essentially making what I'm testing the same as my test bench. I'm going to try to create an actual test bench in a separate file. – John Roberts Jan 26 '13 at 19:42
  • Hey man, I have switched to using a test bench, but I get the same result. Could you check out my modified question? – John Roberts Jan 26 '13 at 21:21

1 Answers1

1

You use registers in your design. So you need to add a signal to your clock input:

constant tb_clk_period : time       := (1 sec) / 10_000_000; -- 10 MHz
signal   tb_clk        : std_ulogic := '0';
...
-- clock generator
tb_clk <= not tb_clk after tb_clk_period / 2;
user2099996
  • 124
  • 3