timescale definition in modelsim [closed] - time

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have an issue while simulating my system with a verilog bench. I have a signal (clk_out) from which I want to measure and auto-check the period and both high and low time. Signal clk_out has a period of 1 second and both high time and low time are 500ms.
`timescale 1ms / 1ps
module tb;
parameter PASSED = 1;
parameter FAILED = 0;
wire clk_out;
reg reset_n;
reg result;
realtime time1;
realtime time2;
realtime time3;
initial begin
result = PASSED;
reset_n = 1'b0;
// stay in reset for 100ms
reset_n = #100 1'b1;
#(negedge clk_out);
time1 = $realtime;
#(posedge clk_out);
time2 = $realtime;
#(negedge clk_out);
time3 = $realtime;
$display("\n");
$display("period is %f, high time is %f, and low time is %f",time3-time1,time3-time2,time2-time1);
$display("\n");
if (time3-time1 <= 999 || time3-time1 >= 1001) begin
result = FAILED;
end
if (time2-time1 <= time3*0.998/2 || time2-time1 >= time3*1.002/2) begin
result = FAILED;
end
if (time3-time2 <= time3*0.998/2 || time3-time2 >= time3*1.002/2) begin
result = FAILED;
end
$display("\n");
$display("=================================================");
if (result) begin
$display("Test is PASSED");
end else begin
$display("Test is FAILED");
end
// create the 1Hz signal when not in reset
my_module my_module_under_test
(
.RESET_N (reset_n),
.CLK_OUT (clk_out)
);
modelsim output is as follow :
period is 1000000000.000000, high time is 500000000.000000, and low time is 500000000.000000
=================================================
test is FAILED
=============== END OF SIMULATION ===============
It seems that the timescale define at the file top is not read by the simulator. I expected to have :
time3 - time1 = 1000.00000
time2 - time1 = 500.00000
time3 - time2 = 500.00000
What am I doing wrong ?
Thanks

I have converted your code to a self contained test, no my_module, on EDA Playground.
It outputs as you expected.
# time3-time1 : 1000.000000
# time3-time2 : 500.000000
# time2-time1 : 500.000000
If your still having the issue I would suggest there is an issue is in the my_module that the clock is not running at the correct frequency.
Tips:
1) I would change the way your applying your reset from:
// stay in reset for 100ms
reset_n = #100 1'b1;
to
// stay in reset for 100ms
#100ms reset_n = 1'b1;
The last version will sequentially wait for 100ms then release the reset, before moving on to the rest of the test program.
2) If your simulator supports it using time specifiers helps remove reliance on the timescale. ps pico seconds, ns nanoseconds, ms milliseconds, s seconds.

Two possibilities:
Check the timescale declared above module my_module(...), the module will use this time scale. If the time scale is not declared in the file, then it will used the most recently declared timescale; compiling order matters. If no previously compiled timescale is declared, then it will use the simulators default timescale.
if the command line option -timescale timeunit/timeprecision it is used, it will the global timescale and any declaration in the verilog files will be ignored.

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

Different instances of a System Verilog Module have different behaviour

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)

block ram (BRAM) read and write using different clocks

I am relatively new to some advanced VHDL programming and have a problem i have been facing for a while.
I will try to be very thorough in my problem description.
I am using a Digilent Nexys-3 board with SPARTAN - 6 FPGA
Here is what i am trying to implement:
Read data from ADC SPI bus and store it into the BRAM.
For this i instantiate a block RAM using a memory IP core generator
ADC_BRAM: bram
port map( ..
..
addra => addra,
dina => ADC_DATA,
..
..
);
The addra, ADC_DATA (data on SPI bus stored into a std_logic_vector) is assigned during the "read_adc" state of the FSM in the ADC module.
After the ADC has sampled 100 points I stop writing into the BRAM
main: process(clk)
begin
if(rising_edge(clk)) then
case state is
when read_adc =>
.....
.....
.....
if(addra < "1100100") then
.....
<some code>
addra <= addra + 1;
.....
elsif (addra = "1100100") then
state <= endofconversion;
end if;
when endofconversion =>
addra <= "00000000";
wea <= "0"; -- write enable for BRAM
state <= read_bram;
Next, i want to access the data from the BRAM and send it using USB-UART.
From what i understand all the BRAM's are synchronous and thus have to be implemented with process(clk,reset).
Currently i have implemented the state " read_bram" under the same process as mentioned above
main: process(clk)
begin
if(rising_edge(clk)) then
case state is
<some code>
when endofconversion =>
addra <= "00000000";
wea <= "0"; -- write enable for BRAM
state <= read_bram;
when read_bram =>
....
<some code>
....
end case;
Now the UART clock needs to be much slower than the rate at which ADC has been read.
My question is " How do i implement the read operation of the BRAM using a much slower clock, which will ensure proper functioning of the UART" ?
I also tried another approach where the BRAM module is defined in the top level file and i send the " addra, ADC_DATA" generated from the ADC module into the port map of the BRAM module.
Now, on the top level if i create a slower clock to read the data ("douta") from the BRAM and send it to UART, i need to generate "addra" in this process and send it to BRAM port "addra"
This causes issues of " multiple drivers " connected to signal "addra", as its values changes in the "process()" of both the ADC module (faster clock) and the top level module (slower clock).
Please help me out. I can provide more info if the problem description is not clear.
TLDR; How can i use 2 separate clocks while implementing synchronous memory BRAM
- "faster clock => write into BRAM" -- based on ADC sampling rate
- " slower clock => read from BRAM" -- based on UART clk (slower BAUD rate than ADC sampling speed)

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;

Warning "has no load", but I can't see why

I got these warnings from Lattice Diamond for each instance of any uart (currently 11)
WARNING - ngdbuild: logical net 'UartGenerator_0_Uart_i/Uart/rxCounter_cry_14' has no load
WARNING - ngdbuild: logical net 'UartGenerator_0_Uart_i/Uart/rxCounter_cry_0_COUT1_9_14' has no load
WARNING - ngdbuild: logical net 'UartGenerator_0_Uart_i/Uart/rxCounter_cry_12' has no load
WARNING - ngdbuild: logical net 'UartGenerator_0_Uart_i/Uart/rxCounter_cry_10' has no load
WARNING - ngdbuild: logical net 'UartGenerator_0_Uart_i/Uart/rxCounter_cry_8' has no load
WARNING - ngdbuild: logical net 'UartGenerator_0_Uart_i/Uart/rxCounter_cry_6' has no load
WARNING - ngdbuild: logical net 'UartGenerator_0_Uart_i/Uart/rxCounter_cry_4' has no load
WARNING - ngdbuild: logical net 'UartGenerator_0_Uart_i/Uart/rxCounter_cry_2' has no load
WARNING - ngdbuild: logical net 'UartGenerator_0_Uart_i/Uart/rxCounter_cry_0' has no load
The VHDL-code is
entity UART is
generic (
dividerCounterBits: integer := 16
);
port (
Clk : in std_logic; -- Clock signal
Reset : in std_logic; -- Reset input
ClockDivider: in std_logic_vector(15 downto 0);
ParityMode : in std_logic_vector(1 downto 0); -- b00=No, b01=Even, b10=Odd, b11=UserBit
[...]
architecture Behaviour of UART is
constant oversampleExponent : integer := 4;
subtype TxCounterType is integer range 0 to (2**(dividerCounterBits+oversampleExponent))-1;
subtype RxCounterType is integer range 0 to (2**dividerCounterBits)-1;
signal rxCounter: RxCounterType;
signal txCounter: TxCounterType;
signal rxClockEn: std_logic; -- clock enable signal for receiver
signal txClockEn: std_logic; -- clock enable signal for transmitter
begin
rxClockdivider:process (Clk, Reset)
begin
if Reset='1' then
rxCounter <= 0;
rxClockEn <= '0';
elsif Rising_Edge(Clk) then
-- RX counter (oversampled)
if rxCounter = 0 then
rxClockEn <= '1';
rxCounter <= to_integer(unsigned(ClockDivider));
else
rxClockEn <= '0';
rxCounter <= rxCounter - 1;
end if;
end if;
end process;
txClockDivider: process (Clk, Reset)
[...]
rx: entity work.RxUnit
generic map (oversampleFactor=>2**oversampleExponent)
port map (Clk=>Clk, Reset=>Reset, ClockEnable=>rxClockEn, ParityMode=>ParityMode,
ReadA=>ReadA, DataO=>DataO, RxD=>RxD, RxAv=>RxAv, ParityBit=>ParityBit,
debugout=>debugout
);
end Behaviour;
This is a single Uart, to create them all (currently 11 uarts) I use this
-- UARTs
UartGenerator: For i IN 0 to uarts-1 generate
begin
Uart_i : entity work.UartBusInterface
port map (Clk=>r_qclk, Reset=>r_reset,
cs=>uartChipSelect(i), nWriteStrobe=>wr_strobe, nReadStrobe=>rd_strobe,
address=>AdrBus(1 downto 0), Databus=>DataBus,
TxD=>TxD_PAD_O(i), RxD=>RxD_PAD_I(i),
txInterrupt=>TxIRQ(i), rxInterrupt=>RxIRQ(i), debugout=>rxdebug(i));
uartChipSelect(i) <= '1' when to_integer(unsigned(adrbus(5 downto 2)))=i+4 and r_cs0='0' else '0';
end generate;
I can syntesis it and the uarts work, but why I got the warning?
IMHO the rxCounter should use each single possible value, but why each second bit creates the warning "has no load"?
I read somewhere that this mean that these net's aren't used and will be removed.
But to count from 0 to 2^n-1, I need no less than n-bits.
This warning means that nobody is "listening" to those nets.
It is OK to have signals that will be removed in synthesis. Warnings are not Errors! You just need to be aware of them.
We cannot assess what is happening from your partial code.
Is there a signal named rxCounter_cry?
What is the datatype of ClockDivider?
What is the value of dividerCounterBits?
What happens in the other process? If it is irrelevant, please try to run your synthesis without that process. If it is relevant, we need to see it.
Lattice ngdbuild is particularly spammy for the job it is doing, I pipe ngdbuild output through grep in my makefile to remove exactly these messages:
ngdbuild ... | grep -v "ngdbuild: logical net '.*' has no load"
There's more than 2500 of these otherwise, eliminating them helps concentrate on real issues.
Second worst toolchain spammer is edif2ngd complaining about Verilog parameters it does not have explicit handling for. This one is a two line message (over 300 of these) so I remove it with:
edif2ngd ... | sed '/Unsupported property/{N;d;}'
Just be aware that sometimes it implements things with adders. The highest order bit will not use the carry output of that adder, and the lowest order bit will not use the sign input. So you get a warning like:
WARNING - synthesis: logical net 'clock_chain/dcmachine/count_171_add_4_1/S0' has no load
WARNING - synthesis: logical net 'clock_chain/dcmachine/count_171_add_4_19/CO' has no load
No problem, bit 19 is the highest, so it will not carry anywhere, and bit 1 is the lowest, so it does not get a sign bit from anywhere. If, however, you get this warning on any of the bits in between highest and lowest, it normally means something is wrong, but not an error, so it will build something that "works" when you test it, but not in an error case. If you simulate it with error cases it will normally show undesirable results.

Resources