Search code examples
vhdlghdlgtkwave

Unable to output data entered into a register


I have a simple program. I am trying to input the counter output into a memory address register and output the data that is in the memory address register.

Memory Address Register Code:

library ieee;
use ieee.std_logic_1164.all;

entity mar is
port(
    mar_clk, mar_clr, mar_en : in std_logic;
    mar_datain : in std_logic_vector(3 downto 0);
    mar_dataout : out std_logic_vector(3 downto 0)
);
end entity;

architecture behavioral of mar is
begin
    process(mar_clk, mar_clr, mar_en, mar_datain)
        begin
        if(mar_clr = '1') then
            mar_dataout <= (others => '0');
        elsif(mar_clk'event and mar_clk = '1') then
            if(mar_en = '0') then
                mar_dataout <= mar_datain;
            end if;
        end if;
    end process;
end behavioral;

Buffer4 Code:

library ieee;
use ieee.std_logic_1164.all;

entity buffer4 is
port(
    buff4_en : in std_logic;
    datain : in std_logic_vector( 3 downto 0 );
    dataout : out std_logic_vector( 3 downto 0 )
);
end entity;

architecture behavioral of buffer4 is
begin
    process(buff4_en, datain)
    begin
        if(buff4_en = '1') then
            dataout <= datain;
        else
            dataout <= (others => 'Z');
        end if;
    end process;
end behavioral;

Program Counter Code:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity pc is
    port(
        pc_ld, pc_en, pc_clk, pc_rst : in std_logic;
        pc_datain : in std_logic_vector(3 downto 0);
        pc_dataout : out std_logic_vector(3 downto 0)
    );
end entity;

architecture behave of pc is
    signal count : std_logic_vector(3 downto 0) := "0001";
    signal temp : integer;
begin
    process(pc_clk, pc_rst)
    begin
        if(pc_rst = '1') then
            count <= (others => '0');
        elsif(pc_clk'event and pc_clk = '1') then
            if(pc_ld = '1') then
                count <= pc_datain;
            elsif(pc_en = '1') then
                count <= count;
                temp <= conv_integer(count);
                if(temp = 16) then
                    count <= (others => '0');
                end if;
                count <= count + 1;
            end if;
        end if;
    end process;
    pc_dataout <= count;
end behave;

Test Program Code:

library ieee;
use ieee.std_logic_1164.all;

entity test is
end entity;

architecture behave of test is

component mar
    port(
        mar_clk, mar_clr, mar_en : in std_logic;
        mar_datain : in std_logic_vector( 3 downto 0 );
        mar_dataout : out std_logic_vector( 3 downto 0 )    
    );
end component;

component pc
    port(
        pc_ld, pc_en, pc_clk, pc_rst : in std_logic;
        pc_datain : in std_logic_vector(3 downto 0);
        pc_dataout : out std_logic_vector(3 downto 0)   
    );
end component;

component buffer4
    port(
        buff4_en : in std_logic;
        datain : in std_logic_vector( 3 downto 0 );
        dataout : out std_logic_vector( 3 downto 0 )    
    );
end component;

signal databus : std_logic_vector(7 downto 0);
signal addressbus : std_logic_vector(3 downto 0);

signal gclk : std_logic;
signal mar_clr, mar_en : std_logic;
signal pc_ld, pc_en, pc_rst : std_logic;

signal buff4_en : std_logic;
signal dataout : std_logic_vector(3 downto 0);

signal mar_datain, mar_dataout : std_logic_vector(3 downto 0);
signal pc_dataout : std_logic_vector(3 downto 0);

begin
    U1 : pc port map(pc_ld, pc_en, gclk, pc_rst, databus(3 downto 0), pc_dataout);
    U2 : buffer4 port map(buff4_en, pc_dataout, databus(3 downto 0));
    U3 : mar port map(gclk, mar_clr, mar_en, databus(3 downto 0), addressbus);

    stim_process : process
    begin
        gclk <= '0';
        wait for 10 ns;
        pc_ld <= '0';
        pc_en <= '1';
        pc_rst <= '0';
        buff4_en <= '1';
        mar_clr <= '0';
        mar_en <= '0';
        gclk <= '1';
        wait for 10 ns;
    
        gclk <= '0';
        wait for 10 ns;
    
        assert false report "Reached end of test. Start GTKWave";
        wait;
    end process;
end behave;

This is the output when I run the program

GTKwave Simulation

As seen the Memory Address Registers takes the input and doesn't output it on the address bus. How can I make the Memory Address Register output the data on the address bus?


Solution

  • This is the logic for writing to your memory address output register inside your 'MAR' component:

        if(mar_clr = '1') then
            mar_dataout <= (others => '0');
        elsif(mar_clk'event and mar_clk = '1') then
            if(mar_en = '0') then
                mar_dataout <= mar_datain;
            end if;
        end if;
    

    If appears that at your rising edge of clock (mar_clk'event and mar_clk = '1') in the waveforms that mar_clr and mar_en are both undefined U's. They have not got their values yet when the rising edge occurs.

    You need to redo your testbench to make sure input signals are stable+defined before the rising edge so they are sampled correctly. Then mar_dataout <= mar_datain; should take correctly.

    Could try moving initial wait statement like so:

    gclk <= '0';
    pc_ld <= '0';
    pc_en <= '1';
    pc_rst <= '0';
    buff4_en <= '1';
    mar_clr <= '0';
    mar_en <= '0';
    wait for 10 ns;
    gclk <= '1';
    wait for 10 ns;