cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
sebastian_z
Explorer
Explorer
7,947 Views
Registered: ‎04-01-2016

Forcing a signal in a VHDL testbench

Jump to solution

Hi all,

 

I have developed a very simple noise generator for some tests using linear feedback shift registers (e.g. XAPP210). I simulate with Cadence. My problem is the following line:

 

    signal prng_reg             : std_logic_vector(167 downto 0);

The initial value is not important for me because as told it's a very simple random generator (model an ADC input directly in the FPGA with synthesized data).

The simulator only runs correctly when I add (others => '0') else of course the signal is UNDEFINED the whole simulation time. I don't want to do this in this way because then no shift registers from the LUTs are used and the initial state is not important for me so I  want shift registers to be instantiated.

 

In the waveform viewer I can force the signal to be Zero and then release the signal and everything is fine to. The simulation works then. Now I want to to this in my TCL script but Cadence does not provide the exact command. I see the following lines in the console:

 

SimVision> console submit -using simulator -wait no {force :adc_emulator_inst:prng_reg = {"0000 ...... 000"}; }
SimVision> console submit -using simulator -wait no run
SimVision> console submit -using simulator -wait no {release  :adc_emulator_inst:prng_reg}
SimVision> console submit -using simulator -wait no run

Can anybody provide me the correct TCL command for doing this?

 

Google gives me some other solutions when using Verilog instead of VHDL because there the commands $nc_force() and $nc_release() are available. This seems not be the case for VHDL.

 

I hope that anyone can help me.

Thanks in advance.

Sebastian

0 Kudos
1 Solution

Accepted Solutions
sebastian_z
Explorer
Explorer
7,858 Views
Registered: ‎04-01-2016

Hi all,

 

thank you very much for your help! I also found the solution with the help of a colleague. It is not that difficult.

 

I added the following lines in my TCL script:

 

2018-08-27_10h41_29.png

 

Kind regards

Sebastian

View solution in original post

0 Kudos
6 Replies
bruce_karaffa
Scholar
Scholar
7,926 Views
Registered: ‎06-21-2017

This doesn't exactly answer your question, but if you add (OTHERS => '1') instead of (OTHERS => '0'), do you still have a problem?  All ones is a valid state for an LFSR.

0 Kudos
sebastian_z
Explorer
Explorer
7,911 Views
Registered: ‎04-01-2016

My problem is that I don't want an initialization at all, neither Zeros nor Ones. But to be able to simulate that I have to initialize else I just see UNDEFINED and the whole simulation is worthless.

 

So I have to provide a way to init that register with a TCL command or in the VHDL testbench itself else Vivado will not use Shift registers but dedicated registers which is absolutly not what I want.

 

It is only a simulation problem but I want to to it the correct way and not delete the OTHERS-statement after simulation is working. This wouldn't be a good design practice.

 

Kind regards

Sebastian

0 Kudos
brimdavis
Scholar
Scholar
7,899 Views
Registered: ‎04-26-2012

@sebastian_z   "So I have to provide a way to init that register with a TCL command or in the VHDL testbench itself else Vivado will not use Shift registers but dedicated registers which is absolutly not what I want."

 

 Unless Xilinx has broken something recently, an initialization at the point of signal declaration should work just fine, without inhibiting the inference of SRL's.

 

e.g. for an XOR feedback LFSR:

  signal prng_reg  : std_logic_vector(167 downto 0) := ( others => '1' );

 

-----------------

 I also would note that in real world LFSR hardware, logic is needed to insure your LFSR  doesn't end up in the bad all-zeros (XOR feedback) or all-ones (XNOR feedback) state at startup; typically one of the following methods is used:

  - signal initialization as above (synthesizes to SRL initial value set in configuration bitstream)

  - XOR term forcing at reset

  - all {0|1} lockup state detection logic

 

-Brian

7,893 Views
Registered: ‎01-22-2015

Hi Sebastian,

 

    I don't want to do this in this way because then no shift registers from the LUTs are used and the initial state is

    not important for me so I want shift registers to be instantiated.

I don’t quite understand the problem.

 

However, below is a short VHDL component, RN32_GEN.vhd, that we put together from XAPP210 and from VHDL found <here>.

----------------------------------------------------------------------------------
-- Create Date: 03Nov16 
-- Module Name: RN32_GEN.vhd
----------------------------------------------------------------------------------
-- Description:
-- This module use a linear feedback shift register (LFSR) to produce a 32-bit pseudo random number.
-- VDHL code was found at: 
--      http://stackoverflow.com/questions/1125640/how-to-generate-pseudo-random-number-in-fpga  
-- 
-- Usage and Notes:
--  1) Specify value of RNMX = maximum value of the reported random number, RNR
--  2) Maximum size of RNR and RNMX is 32-bit.
--  3) Start toggling CLK and start reading pseudo-random numbers from output, RNR.
--      NOTE: at startup, it takes about 64 toggles of CLK before RNR is random.
--  4) Output, RNS, is a random bit that can be used as the sign of RNR.
--      NOTE: the value of RNS is equal to the value of the most-significant-bit (MSB)
--      reported by the 32-bit random number generator used in this module
--  5) When RNMX is expressible as (2^N -1) then (after the 64 cycle-of-CLK startup)  
--      every tic of CLK will produce a new value of RNR, otherwise RNR may not update 
--      on every tic of CLK. However, having a new value of RNR on every tic of CLK is 
--      usually not needed. 
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity RN32_GEN is
port(
    CLK  : in std_logic;                --clock
    RNMX : in unsigned(31 downto 0);    --max value of RNR
    RNS  : out std_logic;               --sign(+/-) bit for RNR
    RNR  : out unsigned(31 downto 0)    --pseudo random number (0-to-RNMX)
);
end RN32_GEN;

architecture BEHAVIOR of RN32_GEN is
signal rn32 : unsigned(31 downto 0) := x"00000000";

begin

--Create the 32-bit random number, rn32
RNG: process(CLK)
  function lfsr32(x : unsigned(31 downto 0)) return unsigned is
  begin
        return x(30 downto 0) & (x(0) xnor x(1) xnor x(21) xnor x(31));
  end function;
begin
  if rising_edge(CLK) then
    rn32 <= lfsr32(rn32);
  end if;
end process RNG;

--Create RNR from rn32 and limit the value of RNR to RNMX
LMR: process(CLK,rn32)
variable rnrv : unsigned(31 downto 0);
variable done1 : std_logic;
variable J : integer range 0 to 31;
begin
  if rising_edge(CLK) then
  
    done1 := '0';          
    L1: for I in 0 to 31 loop           
        J := 31 - I;
        if(done1 = '0') then
            if(RNMX(J) = '1') then      --First nonzero bit in RNMX determines when
                done1 := '1';           --to start placing bits from rn32 into rnrv
                rnrv(J) := rn32(J);
            else
                rnrv(J) := '0';
            end if;
        else
            rnrv(J) := rn32(J);
        end if;
    end loop L1;
    
    if(rnrv < RNMX) then                --If generated random number, rnrv, is less                              
        RNR <= rnrv;                    --than RNMX then move rnrv to RNR, otherwise
    end if;                             --leave value of RNR unchanged.             
    
    RNS <= std_logic(rn32(31));         --sign bit for RNR
  end if;
end process LMR;
end BEHAVIOR;

 

 

In RN32_GEN.vhd you will find the following line of code:

  signal rn32 : unsigned(31 downto 0) := x"00000000";

 

 

As you did, we put the VHDL initialization, := x"00000000", on this line to keep simulation from reporting UNDEFINED values. After you are done with simulation, the VHDL initialization does not need to be erased – because leaving it in your code does no harm.  In fact, this particular VHDL initialization simply describes what Xilinx FPGAs do anyway at power-up (see Xilinx WP272 <here>).

 

     My problem is that I don't want an initialization at all, neither Zeros nor Ones.

My point is that Xilinx FPGA's will automatically do this initialization at power-up, whether you want it or not.

 

I hope you find RN32_GEN.vhd and my explanations useful.

 

Cheers,

Mark

0 Kudos
richardhead
Scholar
Scholar
7,876 Views
Registered: ‎08-01-2012

@sebastian_zThe TCL commands are inside {} force and release commands. But these are really for fault injection and override what's already in the simulation. You really should use and initial value.

 

If you use vhdl 2008, you can use an external name to access the internal signal and new force and release vhdl commands to do this from within your test bench ( but the above comment still applies, you should really leave the uut alone internally. )

sebastian_z
Explorer
Explorer
7,859 Views
Registered: ‎04-01-2016

Hi all,

 

thank you very much for your help! I also found the solution with the help of a colleague. It is not that difficult.

 

I added the following lines in my TCL script:

 

2018-08-27_10h41_29.png

 

Kind regards

Sebastian

View solution in original post

0 Kudos