Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

Weird negative logic issues

I'm trying to write a stream of data into SRAM in the following way. When valid data comes in, I want to write it to memory. When valid is deasserted I want to write 12 bytes of 0's to memory. I'm having some issues getting my counters and signals to work the way I want to. For some reason my write signal is behaving exactly the opposite of what I want it to. For example, this line of code:

wrenframe <= '1' when (valid = '1' or counter > 1) else '0';

When this simulates my simulation results show wrenframe as 0 when the condition is true and 1 otherwise. I'm not sure why this is occurring. It does however write to memory even though wrenframe is 0.

Also, there's a little timing issue with wrenframe in that I need it to be '1' when counter > 0 and counter > 0 on a falling edge but I need to recognize that falling edge earlier. The only way I can think to do it is by using the falling edge of the clock but that seems like bad form


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all; 
--This version starts storing frames at address 0, so you can store a bunch of frames and then send them all out at once
entity framestore is
	port
	(
		clk,reset : in std_logic;
		input: in std_logic_vector(3 downto 0); -- the input ethernet frame
		valid: in std_logic; --valid signal that comes with input
		readEN: in std_logic; --high when we want to read from memory
		output : out std_logic_vector(3 downto 0) --output, has value if we're reading
	);
end framestore;
architecture structure of framestore is
	signal holdout: std_logic_vector(3 downto 0);
	signal address: std_logic_vector(14 downto 0);
	signal next_address: std_logic_vector(14 downto 0);
	signal regRead: std_logic;
	signal regValid: std_logic;
	signal readEN_RE: boolean;
	signal valid_FE: boolean;
	signal wrenframe: std_logic;
	signal counter: integer range 0 to 23;
	
	component ram4bits is
	PORT
	(
		address		: IN STD_LOGIC_VECTOR (14 DOWNTO 0);
		clock		: IN STD_LOGIC  := '1';
		data		: IN STD_LOGIC_VECTOR (3 DOWNTO 0);
		wren		: IN STD_LOGIC ;
		q		: OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
	);
	end component;
begin	
	process(clk,reset,valid,readEN)
	begin
		if(reset = '1') then
			next_address <= "000000000000000";
			regRead <= '0';
			regValid <= '0';
		elsif(clk'event and clk = '1') then
			regRead <= readEN;
			regValid <= valid;
			if(readEN_RE) then
				next_address <= "000000000000000";
			elsif(valid = '1' or readEN = '1') then
				next_address <= address + '1';
				counter <= 0;
			elsif(valid_FE or counter > 0) then
				counter <= counter + 1;
			end if;
			if(valid = '0' and readEN = '0' and counter > 0) then
				next_address <= address + '1';
			end if;
			if(counter = 24) then
				counter <= 0;
			end if;
		end if;
	end process;
	
	store: ram4bits port map(address,clk,input,wrenframe,holdout);
	
	readEN_RE <= regRead = '0' AND readEN = '1';
	valid_FE <= regValid = '1' AND valid = '0';
	wrenframe <= '1' when (valid = '1' or counter > 0) else '0';
	output <= holdout when readEN = '1' else "0000";
	address <= next_address;
end structure;

9 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Well I fixed that problem somehow, but I have another one. My write signal is working but if I don't put in the output so that I can see my write enable signal it misses the first nib. If I just put in the output signal, it gets the first nib. I don't see why the presence or absence of a test signal should influence the result.

    
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_arith.all;
    use ieee.std_logic_unsigned.all; 
    --This version starts storing frames at address 0, so you can store a bunch of frames and then send them all out at once
    entity framestore is
    	port
    	(
    		clk,reset : in std_logic;
    		input: in std_logic_vector(3 downto 0); -- the input ethernet frame
    		valid: in std_logic; --valid signal that comes with input
    		readEN: in std_logic; --high when we want to read from memory
    		wrenout: out std_logic;
    		output : out std_logic_vector(3 downto 0) --output, has value if we're reading
    	);
    end framestore;
    architecture structure of framestore is
    	signal holdout: std_logic_vector(3 downto 0);
    	signal address: std_logic_vector(14 downto 0);
    	signal next_address: std_logic_vector(14 downto 0);
    	signal regRead: std_logic;
    	signal regValid: std_logic;
    	signal readEN_RE: boolean;
    	signal valid_FE: boolean;
    	signal wrenframe: std_logic;
    	signal counter: integer range 0 to 23;
    	
    	component ram4bits is
    	PORT
    	(
    		address		: IN STD_LOGIC_VECTOR (14 DOWNTO 0);
    		clock		: IN STD_LOGIC  := '1';
    		data		: IN STD_LOGIC_VECTOR (3 DOWNTO 0);
    		wren		: IN STD_LOGIC ;
    		q		: OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
    	);
    	end component;
    begin	
    	process(clk,reset,valid,readEN)
    	begin
    		if(reset = '1') then
    			next_address <= "000000000000000";
    			regRead <= '0';
    			regValid <= '0';
    		elsif(clk'event and clk = '1') then
    			regRead <= readEN;
    			regValid <= valid;
    			if(readEN_RE) then
    				next_address <= "000000000000000";
    			elsif(valid = '1' or readEN = '1') then
    				next_address <= address + '1';
    				counter <= 0;
    			elsif(valid_FE or counter > 0) then
    				counter <= counter + 1;
    			end if;
    			if((valid = '0' and readEN = '0' and counter > 0) or valid_FE) then
    				next_address <= address + '1';
    			end if;
    			if(counter = 25) then
    				counter <= 0;
    			end if;
    		end if;
    	end process;
    	
    	store: ram4bits port map(address,clk,input,wrenframe,holdout);
    	
    	readEN_RE <= regRead = '0' AND readEN = '1';
    	valid_FE <= regValid = '1' AND valid = '0';
    	wrenframe <= '1' when (valid = '1' or counter > 0 or valid_FE) else '0';
    	output <= holdout when readEN = '1' else "0000";
    	address <= next_address;
    	
    	wrenout <= wrenframe; --this is the line that makes things work if it's present
    end structure;
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    To allow other users to reproduce the problem exactly as you experienced it, it would be a good idea to pack the example design with a test *.wvf file to a quartus archive and post it here.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I don't see the issue right away, but you might try removing everything but clock and reset from the sensitivity list in the process. I also notice that the signal 'counter' is not assigned during reset.

    For general readability you should try to just assign one output per process - so your code would have 4 processes. It will make your life much easier. :)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    how do you know what to put in a sensitivity list? I figured it'd be easier to do it all in one block because then I'd have repeated code in places.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    how do you know what to put in a sensitivity list? I figured it'd be easier to do it all in one block because then I'd have repeated code in places.

    --- Quote End ---

    Generally speaking, for synchronous designs you should only have clock and reset in the sensitivity list. You need to understand how the synthesizer will implement the hardware otherwise.

    The repeated code is very minimal and it is well worth what you gain in readability. Trust me on this one.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    for synchronous designs you should only have clock and reset in the sensitivity list

    --- Quote End ---

    You may want to write need only instead of should only have . Furthermore, sensitivity lists actually have no meaning in synthesized code, they are important in simulation only.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    You may want to write need only instead of should only have . Furthermore, sensitivity lists actually have no meaning in synthesized code, they are important in simulation only.

    --- Quote End ---

    agreed they have no meaning (nowadays anyway). Still will mess up simulation though.