Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17255 Discussions

Weird negative logic issues

Altera_Forum
Honored Contributor II
1,619 Views

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;
0 Kudos
9 Replies
Altera_Forum
Honored Contributor II
884 Views

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;
0 Kudos
Altera_Forum
Honored Contributor II
884 Views

I resolved it. Not sure how

0 Kudos
Altera_Forum
Honored Contributor II
884 Views

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.

0 Kudos
Altera_Forum
Honored Contributor II
884 Views

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. :)
0 Kudos
Altera_Forum
Honored Contributor II
884 Views

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.

0 Kudos
Altera_Forum
Honored Contributor II
884 Views

 

--- 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.
0 Kudos
Altera_Forum
Honored Contributor II
884 Views

Thanks, I'll work on that

0 Kudos
Altera_Forum
Honored Contributor II
884 Views

 

--- 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.
0 Kudos
Altera_Forum
Honored Contributor II
884 Views

 

--- 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.
0 Kudos
Reply