Register initialization

A

Aji

Hi,

I first started innocently with :

library IEEE;
use IEEE.Std_Logic_1164.all;

architecture LFSR of BitGen is
begin
process
variable R : Std_logic_Vector(31 downto 0):= X"00000001";
variable X : Std_logic;
begin
end if;
wait until Clk='1' and not Clk'stable;
X := (R(31) xor R(6) xor R(5) xor R(2) xor R(0));
R := R(30 downto 0) & X ;
b <= X;
end process;
end LFSR;

Then I realized that my register with initialized with 0 instead of 1. So I
changed it with :

library IEEE;
use IEEE.Std_Logic_1164.all;

architecture LFSR of BitGen is
begin
process
variable R : Std_logic_Vector(31 downto 0):= Seed;
variable X : Std_logic;
begin
if R=X"00000000" then
R := X"00000001";
end if;
wait until Clk='1' and not Clk'stable;
X := (R(31) xor R(6) xor R(5) xor R(2) xor R(0));
R := R(30 downto 0) & X ;
b <= X;
end process;
end LFSR;

Is it a common way to initialize registers ? what about using a reset signal
and a read into memory ? Are there common practices or it just depends on
the design requirements (memory and logic available) ?
 
A

Arnaud

Why aren't you using the common way to design a register ? Because what
you're writing here, with the keyword 'wait' isn't synthetisable.

Why not write something like that ?

architecture LFSR of BitGen is
begin
XOR_PROC : process(clk, rst)
variable R : std_logic_vector(31 downto 0);
variable X : std_logic;
begin
if rst = '0' then
X := '0';
R := X"00000001";
b <= (others => '0');
elsif rising_edge(clk) then
X := (R(31) xor R(6) xor R(5) xor R(2) xor R(0));
R := R(30 downto 0) & X ;
b <= X;
end if;
end process XOR_PROC;
end LFSR;
 
A

Arnaud

And instead of using variables, why don't you use a combinatorial
statement?

something like that :

architecture LFSR of BitGen is
signal X : std_logic;
signal R : std_logic_vector(31 downto 0);
begin
-- combinatorial part
X <= R(31) xor R(6) xor R(5) xor R(2) xor R(0);

-- sequential part
XOR_PROC : process(clk, rst)
begin
if rst = '0' then
R <= X"00000001";
b <= '0';
elsif rising_edge(clk) then
R <= R(30 downto 0) & X ;
b <= X;
end if;
end process XOR_PROC;
end LFSR;
 
A

Andy

"... why don't you use a combinatorial statement?"

Because clocked process descriptions simulate faster (approaching cycle
based speed in good simulators). Separate processes (implied or
explicit) with the same sensitivity list (i.e. clk, rst) can be merged
into one process by the simulator. Concurrent statements rarely share
the same implied sensitivity list, and must be executed as separate
processes.

Also, a single process allows the use of variables that are not only
more efficient, but their local scope provides additional protection.

Finally, since X is purely combinatorial in the single process version,
it should not have a reset.

Andy
 
M

Mike Treseler

Andy said:
Because clocked process descriptions simulate faster (approaching cycle
based speed in good simulators). Separate processes (implied or
explicit) with the same sensitivity list (i.e. clk, rst) can be merged
into one process by the simulator. Concurrent statements rarely share
the same implied sensitivity list, and must be executed as separate
processes.

Also, a single process allows the use of variables that are not only
more efficient, but their local scope provides additional protection.
Finally, since X is purely combinatorial in the single process version,
it should not have a reset.

Well said Andy.

I got on the single-process bandwagon,
when I also noticed that Modelsim was
combining my processes for me.

Following the synchronous process template is
very viable way to "think hardware"

-- Mike Treseler

__________________________
begin -- process template
if reset = '1' then
init_all_regs; -- reg_v := init_c;
elsif rising_edge(clock) then
update_process_regs; -- reg_v := f(reg_v, );
end if;
update_output_ports; -- out_port <= reg_v;
end process sync_template;
 
A

Arnaud

I've had so many problems with Ncsim when using variables (counters
declared as variables for instance which only count until 1 in some
versions of Ncsim) that i now try to avoid them as often as possible.

However I agree with the fact that if it were corretly handled, it
could bring some advantages.
 
M

Mike Treseler

Arnaud said:
I've had so many problems with Ncsim when using variables (counters
declared as variables for instance which only count until 1 in some
versions of Ncsim)

Does that mean that the latest version works ok?
that i now try to avoid them as often as possible.

Do you have a code example?
Are you sure it wasn't just
a question of variable use
before or after update?
It's normal to get a wire
if you USE after UPDATE.

If you still have access to ncsim,
would you mind running http://home.comcast.net/~mike_treseler/test_uart.vhd
in text mode and see if you get an ALL_PASS ?
That would prove the point one way or the other.

Thanks.

-- Mike Treseler
 
A

Andy

I've used variables (local, not shared) in ncsim for a long time, with
no problems that were not self-inflicted. There were some early issues
with the waveform viewer, but those are solved now.

Andy
 
A

Aji

Why aren't you using the common way to design a register ? Because what
you're writing here, with the keyword 'wait' isn't synthetisable.

Why not write something like that ?
Because I am a beginner and I don't know anything of this. I am just asking
to learn.

Thanks you for your replies.
 
A

Arnaud

In fact, you're right, it's working with some versions of ncsim, but
not obviously with the latest !

Actually, I developped an IP, compiling and simulating it using ncsim
4.1. A year after, this IP was used by colleagues in a project in which
they were using ncsim 5.1. They launched again all my scripts to check
the non regression, and it the results were not good anymore. After
looking for the reason, we discovered that all my counters declared
locally as variables in the processes were only counting until 1 with
ncsim 5.1 while they were working correctly with ncsim4.1.

After calling Cadence hotline, they told us that a new bug had appeared
in v5.1 which didn't exist in previous versions and they advised us to
change the variables into signals, which I had to do in all my files...
This made me waste lots of time, and that's the reason why I no longer
use variables.

I'm afraid I can't check whether you're file is working correctly with
ncsim 5.1 as I only have access to 4.1 here (with which my counters are
handled correctly).

Here is a part of a file using a counter declared as a local variable:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

architecture rtl of rxflagdet is

signal Abort : std_logic; -- Abort sequence detected
signal Flag : std_logic; -- Flag detected
signal FlagFound : std_logic; -- Flag detected valid when
RxEnable = '1'

signal ShiftReg : std_logic_vector(7 downto 0); -- Shift Register
signal SynchReg : std_logic; -- synchro of RxData on RxClk

signal AbortFound_i: std_logic; -- intermediate signal
signal CtrlAbort : std_logic; -- control of the Abort generation
signal RxDout1 : std_logic; -- Delay RxDout one more RxClk
cycle

type StateType is (HUNT, READ); -- FSM states
signal State : StateType;

constant POLAR_RST : std_logic := '0';

begin

-------------------------------------------------------------------------------
RX_DATA_AVAIL : process(RxClk, Rstn)
-- Generates RxDataAvail and StartOfFrame
variable CountBits : integer range 7 downto 0;
variable FlagDetect : std_logic;

begin
if Rstn = POLAR_RST then -- asynchronous reset
(active low)
State <= HUNT;
CountBits := 0;
FlagDetect := '0';
RxDataAvail <= '0';
StartOfFrame <= '0';

elsif RxClk'event and RxClk = '1' then
case State is
when HUNT =>

RxDataAvail <= '0';
StartOfFrame <= '0';

if FlagFound = '1' then -- Flag detected. wait 7
cycles to see if it
CountBits := 0; -- is followed by another
flag or by valid bits
FlagDetect := '1';
elsif FlagDetect = '1' then
if CountBits = 7 then -- Valid Data is following
the flag.
State <= READ;
CountBits := 0; -- Counter reinitialised
RxDataAvail <= '1'; -- First bit of the frame ->
valid bit
StartOfFrame <= '1'; -- The flag detected is not
followed by another flag
else
CountBits := CountBits + 1; -- if a new flag is not
detected 7 RxClk cycles after
-- the current flag, a frame
is starting
end if; -- CountBits = 7
end if; -- FlagFound = '1'

when others => -- READ

if FlagFound = '1' or AbortFound_i = '1' or RxEnable = '0'
then
-- New flag detected -> End of Frame; Abort detected -> back
to HUNT
-- RxEnable = '0' -> Receiver disabled : back to HUNT mode
State <= HUNT;
RxDataAvail <= '0';
else
-- Dout is valid and stays valid if frame not aborted and
reception not disabled
RxDataAvail <= '1';
end if; -- FlagFound = '1' or AbortFound_i = '1' or RxEnable =
'0'

FlagDetect := FlagFound; --
StartOfFrame <= '0'; -- Frame is already started

end case; -- State

end if; -- Rstn = POLAR_RST
end process RX_DATA_AVAIL;

end rtl;
 
C

Colin Marquardt

Mike Treseler said:
If you still have access to ncsim,
would you mind running http://home.comcast.net/~mike_treseler/test_uart.vhd
in text mode and see if you get an ALL_PASS ?

ncsim: 05.10-s006 PASS, also 5.3 - 5.6.

ncsim: 05.00-s005 FAIL (also 3.3, 4.0, 4.1):

$ make
ncvhdl -v93 uart.vhd test_uart.vhd
ncvhdl: 05.00-s005: (c) Copyright 1995-2003 Cadence Design Systems, Inc.
return TxBitSampleCount_v = roll_c; -- counter rollover
|
ncvhdl_p: *E,ILOBJR (uart.vhd,183|37): Illegal object reference in function [2.2].
return RxBitSampleCount_v = roll_c; -- counter rollover
|
ncvhdl_p: *E,ILOBJR (uart.vhd,220|37): Illegal object reference in function [2.2].


$ nchelp ncvhdl_p ILOBJR
nchelp: 05.00-s005: (c) Copyright 1995-2003 Cadence Design Systems, Inc.
ncvhdl_p/ILOBJR =
If a function subprogram references a signal or variable object, then
that object must be declared within the declarative region associated
with the function. The indicated name contains a reference to a global
object. Section [2.2] of LRM [87 & 93].
Examples:
signal S: INTEGER;
function F (P: INTEGER) return BOOLEAN is
variable X: INTEGER;
begin
X := P; -- legal
S <= X; -- illegal
return FALSE;
end;
Only impure function subprogram can reference a quantity or a terminal
object. It is illegal to access a quantity or terminal object from a
function subprogram which is pure.


Impure functions in a procedure were probably still a bit too
devious in 2003 :)

HTH,
Colin
 
M

Mike Treseler

Colin said:
ncsim: 05.10-s006 PASS, also 5.3 - 5.6.
ncsim: 05.00-s005 FAIL (also 3.3, 4.0, 4.1):

Interesting. I'm OK for ncsim 05.10 or later.

Note that Arnauld's variables simed
correctly in 4.1
(where my impure function would have bugged out)

but not in 5.1
(where my extensive use of variables was fine)

So there might have been some other
5.1 incompatibility with Arnauld's code.
Impure functions in a procedure were probably still a bit too
devious in 2003 :)

I expect the case just hadn't come up.

Thanks to Colin for taking the time
to run all those sims.

-- Mike Treseler
 
A

Arnaud

I didn't read the uart.vhd file in details, but I saw it contains an
rtl description and its associated bench. So, if the compilation fails
(as you describe for versions lower than 5.1), the simulation can't be
launched and so I think it then can't return any FAIL or PASS message.

Am I rigth, or is the PASS or FAIL message linked to the behaviour of
the module in simulation (comparison of the outputs of the simulation
to references) ? That is what would really be interesting here !

Thanks

Arnaud
 
C

Colin Marquardt

Arnaud said:
I didn't read the uart.vhd file in details, but I saw it contains an
rtl description and its associated bench. So, if the compilation fails
(as you describe for versions lower than 5.1), the simulation can't be
launched and so I think it then can't return any FAIL or PASS message.

Yes, my "FAIL" is a compile error, not the FAIL from the testbench;
it doesn't get that far.
Am I rigth, or is the PASS or FAIL message linked to the behaviour of
the module in simulation (comparison of the outputs of the simulation
to references) ?

Yeah, that's what it does.
That is what would really be interesting here !

In the cases where ncvhdl successfully compiles design and
testbench, it works as expected.

Do you still have some of the code which didn't work in 5.1 around?

Cheers,
Colin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,109
Latest member
JanieMalco
Top