Different instances of a System Verilog Module have different behaviour - logic

always # (RSTDAC_B or EN or DSR or DSR_B )
begin
if (RSTDAC_B === 1'b0) begin stepp = 1'b0; stepn = 1'b0; end
else if (RSTDAC_B === 1'b1) begin
if (EN & DSR === 1'b1) begin stepn = 1'b1;end
else if (EN & DSR_B === 1'b1) begin stepp = 1'b1;end
end
end
The code above is from a Dynamic Register Module instantiated 8 times in the design. The intention is that when EN(able) is high then either stepp or stepn is high depending on if DSR or DSR_B is high. I am seeing that when DSR_B goes high, stepp and stepn BOTH go high in 6 out of 8 instances. In 2 instances, the design behaves as intended and only stepp goes high when EN & DSR_B are high.
I have seen this happen on multiple tools so I don't think its the tool's fault. Thanks

This is not valid combinational logic. You must make assignments to all variables in all possible branches of your code. You are not doing that with stepn and stepp
If you are using SystemVerilog, you should be using always_comb instead of always #(explicit_list_of_signals)

Related

ERROR:Xst:1534 - Sequential logic for node <rx_data> appears to be controlled by multiple clocks

I am new to VHDL and writing program for receiving the serial data, which is dependent on 2 clocks and one RESET signal.
One is FPGA's main source clock and another one is the external SPI master clock.
The written is like below:
process(reset, main_clk, ext_clk)
begin
if(reset = '0') then
rx_data <= x"0000";
elsif(chip_sel = '0') then
if(ext_clk'event and ext_clk = '1') then
-- rx_data <= rx_data;
if(main_clk'event and main_clk = '1') then
--- receiving data serially
But Xilinx tool is giving error:
ERROR:Xst:1534 - Sequential logic for node <rx_data> appears to be controlled by multiple clocks.
How to overcome this error?
It's because you use 'event on ext_clk and main_clk which the tools use to infer clocks. Your design should only be sensitive to main_clk and reset. De

Array of 1-bit-wide memory

I'm using ISE 14.7 and i'm trying to create design with some 1-bit-wide distributed RAM blocks.
My memory declaration:
type tyMemory is array (0 to MEMORY_NUM - 1) of std_logic_vector(MEMORY_SIZE - 1 downto 0) ;
signal Memory: tyMemory := ( others => (others => '0')) ;
attribute ram_style : string ;
attribute ram_style of Memory : signal is "distributed" ;
My code:
MemoryGen : for i in 0 to MEMORY_NUM - 1 generate
process( CLK )
begin
if rising_edge(CLK) then
if CE = '1' then
DataOut(i) <= Memory(i)(Addr(i)) ;
Memory(i)(Addr(i)) <= DataIn(i) ;
end if ;
end if ;
end process ;
end generate ;
After synthesis i get this warning:
WARNING:Xst:3012 - Available block RAM resources offer a maximum of two write ports.
You are apparently describing a RAM with 16 separate write ports for signal <Memory>.
The RAM will be expanded on registers.
How can i forse xst to use distributed memory blocks with size=ARRAY_LENGTH and width=1?
I can create and use separate memory component(and is works), but i need more elegant solution.
You need to create an entity that describes a variable length 1-bit wide memory, then use a generate statement to create an array of these. While what you have done would provide the functionality you are asking for in a simulator, most FPGA tools will only extract memory elements if your code is written in certain ways.
You can find documentation on what code Xilinx ISE tools will understand as a memory element by selecting the appropriate document for your device here http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_7/ise_n_xst_user_guide_v6s6.htm . Look under 'HDL Coding techniques'.
Note that if your memory length is large, you will not be able to get maximum performance from it without adding manual pipelining. I think you will get a synthesis message if your memory exceeds the intended useful maximum length for distributed memories. Assuming you are using a Spartan 6 device, you can find information on what the useful supported distributed memory sizes are here: http://www.xilinx.com/support/documentation/user_guides/ug384.pdf page 52.
This should inferre 16 one bit wide BlockRAMs:
architecture ...
attribute ram_style : string;
subtype tyMemory is std_logic_vector(MEMORY_SIZE - 1 downto 0) ;
begin
genMem : for i in 0 to MEMORY_NUM - 1 generate
signal Memory : tyMemory := (others => '0');
attribute ram_style of Memory : signal is "block";
begin
process(clk)
begin
if rising_edge(clk) then
if CE = '1' then
Memory(Addr(i)) <= DataIn(i) ;
DataOut(i) <= Memory(Addr(i)) ;
end if ;
end if ;
end process ;
end generate ;
end architecture;

Why can't make work my VHDL program using elsif not recognize one state

I'am a spanish user an newbie on VHDL programming the problems its that I was trying to make a machine state with the CASE but don't work. then i decide to do with ELSIF instruction all its working perfect but the state 0010 its not working a I don't know why its a very ease program but don't understand why y is not working EXCUSE MY POOR ENGLISH but I do my best thanks I show the program next:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
--definimos identidad de la interfaz
entity interfaz is
port(
sen:in std_logic_vector(3 downto 0);--entrada de sensor bus de 4 bits
clk:in std_logic;
mda, mdr, mia, mir:out std_logic);--mdr,mda=motor derecho retroceso,avance == mia,mir=motor izquiero avance,retroceso
end interfaz;
--comenzando arquitectura de interfaz
architecture behavior of interfaz is
----------------------------------------------------
--Instruccion con herramienta elseif
process
begin
wait until clk'event and clk='1';
if (sen=(0000)) then --alto
mda<='0';
mdr<='0';
mia<='0';
mir<='0';
elsif (sen=(0001)) then --retroceso
mda<='0';
mdr<='1';
mia<='0';
mir<='1';
elsif (sen=0010) then --avance
mda<='1';
mdr<='0';
mia<='1';
mir<='0';
elsif (sen=(0100)) then --izquierda
mda<='0';
mdr<='1';
mia<='1';
mir<='0';
elsif (sen=(1000)) then --derecha
mda<='1';
mdr<='0';
mia<='0';
mir<='1';
end if;
end process;
end behavior;
The sen=0010 appears like sen is compared to a 4-bit vector, but it is
actually compare with the decimal value 0010 = 10 = ten, due to the lack of
"" around the 0010 value. Fix this in all place with by adding "", like
"0010".
VHDL is basically strong typed, but the use ieee.std_logic_unsigned.all; adds
functions that allows compare between std_logic_vector and integer, and for
this reason the problem passes syntax check.
Also:
Fix a syntax error by adding begin before the process, since that is
required in architecture
Consider using if rising_edge(clk) instead of wait until clk'event and clk='1'
Consider rewrite with case

How to solve error occurring in the following vhdl code?

The error is: "ERROR:Xst:528 - Multi-source in Unit on signal nfw".
process(rst_n,dword_int,sync_csw_reg,sync_dw_reg)
begin
if(rst_n='1')then
noofwords<="00000";
no_words<="00000";
nfw<='1';
elsif(falling_edge(sync_csw_reg) and dword_int(10)='0' and nfw='1' )then
noofwords<=dword_int(0 to 4);
check_nfw<=dword_int(0 to 4);
end if;
end process;
process(sync_dw_reg,noofwords)
begin
if(falling_edge(sync_dw_reg))then
if(no_words = noofwords)then
no_words<="00000";
nfw<='1';
else
no_words<= no_words+'1';
nfw<='0';
end if;
end if;
end process;
The problem is that you are assigning the signal nfw from within two processes. That's not possible. You would have to use two different signals (if you need them) and somehow combine them combinationally. Resp.: You could add a if (rst_n='1') into the second process and assign the reset value of nfw there.

Can anybody let me know what is the problem with the following vhdl code?

I am getting error as "ERROR:Xst:827 - "C:/1553/decoder_copy/decoder.vhd" line 265: Signal no_words cannot be synthesized, bad synchronous description".
process(rst_n,dword_int,sync_csw_reg,sync_dw_reg)
begin
if(rst_n='1')then
noofwords<="00000";
no_words<="00000";
nfw<='1';
elsif(falling_edge(sync_csw_reg) and dword_int(10)='0' and nfw='1' )then
noofwords<=dword_int(0 to 4);
check_nfw<=dword_int(0 to 4);
elsif(falling_edge(sync_dw_reg))then
if(no_words = noofwords)then
no_words<="00000";
nfw<='1';
else
no_words<= no_words+'1';
nfw<='0';
end if;
end if;
end process;
I guess it's because you are checking for the edge of two different signals (sync_csw_reg and sync_dw_reg) in one process. You cannot do that if you want to synthesize the code. You have to separate it into two processes.

Resources