LSFR counter for random number - random

module LSFR_counter
#(parameter BITS = 5)
(
input clk,
input rst_n,
output reg [4:0] data
);
reg [4:0] data_next;
always #* begin
data_next[4] = data[4]^data[1];
data_next[3] = data[3]^data[0];
data_next[2] = data[2]^data_next[4];
data_next[1] = data[1]^data_next[3];
data_next[0] = data[0]^data_next[2];
end
always_ff #(posedge clk or negedge rst_n) begin
if(!rst_n)
data <= 5'h1f;
else
data <= data_next;
end
endmodule
This is code for LSFR for 4 bit number. I want to implement N bit Random number generator for an FPGA board.

N is normally reserved for the state of the LFSR, M would be good to use for the number of random bits we wish to generate.
A standard LFSR generates 1 bit of random data, if consecutive bits of the LFSR are used they can be highly correlated, especially if taking a multi-bit value every clock cycle. To remove this correlation we can overclock the lfsr, say 4 times to generate 4 bits. The alternative to the this is to calculate the equations (feedback polynomials) that you would get for each bit. For every clock its internal state (as represented by the N-bits of the LFSR) would move forward 4 steps. Both techniques for over clocking or creating the feedback taps to move the state forward more than 1 step are known as leap-forward.
The code example in the question has been taken from a previous question and answer, this is an example of manually creating the extra feedback for a leap-forward lfsr.
The maths to do this can be done by generating the transition matrix and raising to the power of the number of steps we wish to move forward.
Quick 4-bit LFRS example: with transition matrix a:
a =
0 1 0 0
0 0 1 0
0 0 0 1
1 0 0 1
Feedback is XOR of the first and last bit, seen on last row of the matrix. All other rows are just a single shift. The output of this LFSR is good for one bit. Two bits would suffer from a high correlation, unless it was overclocked.
>> a^2
ans =
0 0 1 0
0 0 0 1
1 0 0 1
1 1 0 1
If we want two bits we need to square the transition matrix. It can be seen that the first two rows are a shift of two places and we require feedback for two places, ie we are moving the LFSR forward two states for every clock.
Just for confirmation if we wanted three bits:
a^3
ans =
0 0 0 1
1 0 0 1
1 1 0 1
1 1 1 1
The second code example in the previous question went on to parameterise the code so the leap forward calculations did not have to be manually created, skipping all of that lovely maths! However the approach used meant it could not be fully parameterised. Therefore I would like to revisit the example I gave for that question:
module fibonacci_lfsr(
input clk,
input rst_n,
output [4:0] data
);
wire feedback = data[4] ^ data[1] ;
always #(posedge clk or negedge rst_n)
if (~rst_n)
data <= 4'hf;
else
data <= {data[3:0], feedback} ;
endmodule
Now we want to parameterise it:
module fibonacci_lfsr#(
parameter POLYNOMIAL = 4'h9
)(
input clk,
input rst_n,
output [4:0] data
);
//AND data with POLYNOMIAL this
// selects only the taps in the polynomial to be used.
// ^( ) performs a XOR reduction to 1 bit
always #* begin
feedback = ^( POLYNOMIAL & data);
end
//Reseting to 0 is easier
// Invert feedback, all 1's state is banned instead of all 0's
always #(posedge clk or negedge rst_n)
if (~rst_n)
data <= 'b0;
else
data <= {data[3:0], ~feedback};
endmodule
A small step now, Just bring the shift outside of the synchronous loop to help with the step after.
always #* begin
data_next = data;
feedback = ^( POLYNOMIAL & data);
data_next = {data_next[3:0], ~feedback} ; //<- Shift and feedback
end
always #(posedge clk or negedge rst_n)
if (~rst_n)
data <= 'b0;
else
data <= data_next;
TL;DR
Now to control the leap-forward iterations, let the tools do the heavy lifting of multiplying the transition matrix.
module fibonacci_lfsr#(
parameter POLYNOMIAL = 4'h9,
parameter N = 4,
parameter BITS = 2
)(
input clk,
input rst_n,
output [BITS-1:0] random
);
reg [N-1:0] data;
reg [N-1:0] data_next;
reg feedback;
assign random = data[N-1:N-BITS];
always #* begin
data_next = data;
// Compiler unrolls the loop, calculating the transition matrix
for (int i=0; i<BITS; i++) begin
feedback = ^( POLYNOMIAL & data_next);
data_next = {data_next[N-2:0], ~feedback} ;
end
end
always #(posedge clk or negedge rst_n)
if (~rst_n)
data <= 'b0;
else
data <= data_next;
endmodule
Example on EDA Playground.
i++ is part of SystemVerilog. If you can only synthesis plain (pre-2009) Verilog then you will need to declare i as an integer and use i =i+1 in the for loop.

If you want to implement an N-bit LFSR, then because each length of LFSR has a different polynomial, and hence a difference set of taps to XOR to produce the next LFSR value, you will need to have constants or a lookup table describing the different tap points, which the design could then could use, based on 'BITS'.
A simpler way to do it might be to implement say a 32-bit LFSR, then use the least significant N bits of this as your output. This has the added benefit of increasing the repetition period for anything but the maximum length LFSR, giving better randomness in these cases.
If you're going for the first option, look at whether using the Fibonacci form instead of the Galois form will make the design more conducive to parametrization in this way. I can't quite work out which form you are using in your 5-bit example.
I'm a VHDL guy*, so I can't give Verilog code, but VHDL-like-pseudocode (untested) might look like this:
constant TAPS_TABLE : TAPS_TABLE_type := (
"00000011",
"00000110",
...
);
for i in 0 to BITS-2 loop
if (TAPS_TABLE(BITS-2)(i) = '1') then
data_next(i) <= data(0) xor data(i+1)
else
data_next(i) <= data(i+1)
end if;
end for;
This would support BITS being between 2 and 8 inclusive, assuming the table was completed. The constant TAPS_TABLE would be optimised away during synthesis, leaving you with something no less resource-hungry than a manually coded LFSR.
* This question originally had a 'VHDL' tag.

In Addition to the previous answers:
Years ago, Xilinx wrote a good AppNote on how to implement 'pseudo random number generators' (PRNGs). The AppNote has a TAP table for n = 3..168. The TAP table is optimized to allow the usage of shift registers. So a PRNG with n=32 does not use 32 single FFs.
Efficient Shift Registers, LFSR Counters, and Long PseudoRandom Sequence GeneratorsXilinx [XAPP 052][1996.07.07]

Related

if statement problem while converting a vector

im new at vhdl coding, and there is a problem with if statement
so my code is the following
i want to convert a vector(bar), if the statement is true (so in this example if its smaller than 10)
process(bar)
variable tmp : integer;
begin
tmp := to_integer(signed(bar));
if tmp < 10 then
good(3) <= bar(3);
good(2) <= bar(3) xor bar(2);
good(1) <= bar(2) xor bar(1);
good(0) <= bar(1) xor bar(0);
end if;
end process;
but the problem is that the statement is not working, if i put a bigger number for example "1111" it is converting in the same way as it converted before
From the comments it seems you want good to be set to 0 whenever bar >= 10. In that case you can just do:
process(bar)
variable tmp : integer;
begin
tmp := to_integer(signed(bar));
if tmp < 10 then
good(3) <= bar(3);
good(2) <= bar(3) xor bar(2);
good(1) <= bar(2) xor bar(1);
good(0) <= bar(1) xor bar(0);
else
good <= (others => '0');
end if;
end process;
The vector good is only assigned when tmp < 10. So there is a latch inferred by this process.
You need to define what's the "else" value for good in any other conditions.
You state that
if i put a bigger number for example "1111" it is converting in the
same way as it converted before
As Tricky pointed out in a comment above, your problem is this line here:
tmp := to_integer(signed(bar));
^^^^^^
You have not posted an MCVE, so I cannot be sure, but your question implies that bar is 4 bits wide. Assuming that is the case, the value "1111" as a signed number is -1. So, if bar is set to "1111", tmp will be -1. -1 is less than 10, so this if statement will evaluate as true:
if tmp < 10 then
If you consider than "1111" is greater than 10 (ie it's 15), then you need to convert via the unsigned type, ie
tmp := to_integer(unsigned(bar));
^^^^^^^^
The range of a 4-bit signed number is -8 to +7. All the values in that range are less than 10, so your if statement will evaluate as true whatever the value of bar.
The above solution assumes that bar is always zero or positive. If that is not the case, then you need more bits in the signal bar. 5 is enough. A 5-bit signed number has the range -16 to +15.
So, I can see two solutions:
use an unsigned type in your type conversion or
make bar 5 bits
or wider.
Others have pointed out that, assuming this is synthsisable code and assuming that this is intended to be combinational logic, then you are missing a branch in your if statement; you don't drive the signal good in the case that the if statement is false and so if you were to synthesise this code as combinational logic, then you would get latches. But that is not the question you asked.

Signed multiplication result trim

What I have
I've two signed signals, 10b length one of them and 2b the other one.
signal R_S_R : signed(9 downto 0);
signal prbs_sup_u : signed(1 downto 0);
Then I want to multiply them like:
R_S_E <= R_S_R * prbs_sup_u;
Storing the result into another 10b signal.
Why 10b again
Because prbs_sup_u is 2b, and it'll only have [-1, 1] values (only those two). So, although result of multiplication is 12b, I think (only if I'm not mistaken) I should be able to store the posible results of the operation in another 10b signal.
So your question is...
After doing the multiplication, I should be able to dispose of two of the bits from the 12b result.
However, which ones? Since it's a signed signal, I don't know which one are disposable. Of course not the first one, since it's the sign, but after that...
Simply use the resize operation to truncate unrequired MSBs (magnitude) like:
R_S_E <= resize(R_S_R * prbs_sup_u, R_S_E'length);
You can find the documentation in numeric_std.resize:
-- Id: R.1
function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
-- Result subtype: SIGNED(NEW_SIZE-1 downto 0)
-- Result: Resizes the SIGNED vector ARG to the specified size.
-- To create a larger vector, the new [leftmost] bit positions
-- are filled with the sign bit (ARG'LEFT). When truncating,
-- the sign bit is retained along with the rightmost part.
If the prbs_sup_u can only have value 1 or -1, then you can also consider:
if prbs_sup_u = 1 then
R_S_E <= R_S_R;
else -- prbs_sup_u = -1
R_S_E <= - R_S_R;
end if;
The operation may then be more obvious, and the circuit will be smaller, since the implementation does not have to include handling of the unused 0 and -2 values.

vhdl code (for loop)

Description:
I want to write vhdl code that finds the largest integer in the array A which is an array of 20 integers.
Question:
what should my algorithm look like, to input where the sequential statements are?
my vhdl code:
highnum: for i in 0 to 19 loop
i = 0;
i < 20;
i<= i + 1;
end loop highnum;
This does not need to be synthesizable but I dont know how to form this for loop a detailed example explaining how to would be appreciated.
Simply translating the C loop to VHDL, inside a VHDL clocked process, will work AND be synthesisable. It will generate a LOT of hardware because it has to generate the output in a single clock cycle, but that doesn't matter if you are just simulating it.
If that is too much hardware, then you have to implement it as a state machine with at least two states, Idle and Calculating, so that it performs only one loop iteration per clock cycle while Calculating, and returns to the Idle state when done.
First of all you should know how have you defined the array in vhdl.
Let me define an array for you.
type array_of_integer array(19 downto 0) of integer;
signal A : array_of_integer :=(others => 0);
signal max : integer;
-- Now above is the array in vhdl of integers all are initialized to value 0.
A(0) <= 1;
A(1) <= 2;
--
--
A(19)<= 19;
-- Now the for loop for calculating maximum
max <= A(0);
for i in 0 to 19 loop
if (A(i) > max) then
max <= A(i);
end if;
end loop;
-- Now If you have problems in understating that where to put which part of code .. in a ----vhdl entity format .. i.e process, ports, etc... you can reply !

VHDL Design - Clock

Can someone please help me with the following:
Design a digital circuit, using VHDL, to keep track of time in the form of HH:MM:SS. The circuit should produce 6 separate four bit digital outputs (2 four bit outputs for the HH, 2 for the MM, 2 for the SS). The HH can just be a 2 digit number in the range 00 to 99 i.e. it’s not a clock, it just a counter for hours even though 99 hour tapes don’t exist. The time is to be displayed on the 6 right most 7 segment displays of the DE2. You have already designed a 7 segment decoder and driver as part of a previous lab, so that can be used to convert each 4 bit output into a 7 bit signal for each the 7-segment display. Don’t forget to set up the pin planer for these display (and all other signals)
The circuit should have the following single bit inputs: A Clock, an increment, a decrement and a reset. The increment/decrement inputs should cause the tape counter to add or subtract 1 second from the tape time on the next rising edge of the clock signal. If neither the increment or decrement inputs are present, the tape counter does not change. The reset is synchronous to the clock (to avoid glitches accidentally resetting it). The increment and decrement signals are all active high signals (i.e. a logic 1), the reset is active low (logic 0).
You tape counter should handle full hour, minute and second roll over, e.g. if the counter is showing 9:59:59, then the next increment should make it display 10:00:00 and vice versa when decrement is present.
Rather than solving your homework, I'd like to give you an idea. Most designers will tend to implement this clock using digit-by-digit rollover (some digits will rollover from 9-0, others from 5-0). I'd like to propose someting different.
The overall idea is: keep your time value in seconds as an integer. This will greatly facilitate the tasks of incrementing and decrementing. Then, you simply implement a conversion function that returns the number of hours, minutes, and seconds, given an integer number of seconds.
Your clock entity would look like this:
library ieee;
use ieee.std_logic_1164.all;
use work.clock_pkg.all;
entity clock is
port (
clock: in std_logic;
n_reset: in std_logic;
increment: in std_logic;
decrement: in std_logic;
hours: out natural range 0 to 99;
minutes: out natural range 0 to 59;
seconds: out natural range 0 to 59
);
end;
architecture rtl of clock is
signal time_in_seconds: natural range 0 to 359999;
begin
process (clock, n_reset) begin
if rising_edge(clock) then
if n_reset = '0' then
time_in_seconds <= 0;
elsif increment then
time_in_seconds <= time_in_seconds + 1;
elsif decrement then
time_in_seconds <= time_in_seconds - 1;
end if;
end if;
end process;
process (time_in_seconds) begin
(hours, minutes, seconds) <= seconds_to_time_type(time_in_seconds);
end process;
end;
As you can imagine, the workhorse of this solution is the seconds_to_time_type() function. You could implement it like this:
package clock_pkg is
type time_type is record
hours: natural range 0 to 99;
minutes, seconds: natural range 0 to 59;
end record;
function seconds_to_time_type(seconds: in natural) return time_type;
end;
package body clock_pkg is
function seconds_to_time_type(seconds: in natural) return time_type is
variable hh: natural range 0 to 99;
variable mm: natural range 0 to 119;
variable ss: natural range 0 to 119;
begin
hh := seconds / 3600;
mm := (seconds mod 3600) / 60;
ss := (seconds mod 3600) mod 60;
return (hh, mm, ss);
end;
end;
Now you have an entity that outputs separate integer values for hours, minutes, and seconds. Converting those values from integers to BCD, and showing those values on the displays is left as an exercise to the reader.
The typical way of implementing a counting clock is using binary coded decimal (BCD), where each digit consists of a separate n-bit counter, with a range as needed.
For example, in order to count seconds (from 0-59), you could use something like the following code:
process(clk, reset) begin
if(reset='1') then
second_tens <= (others=>'0');
second_ones <= (others=>'0');
elsif(rising_edge(clk)) then
if(count_en='1') then
if(second_ones = 9) then
second_ones <= (others=>'0');
if(second_tens = 5) then
second_tens <= (others=>'0');
-- Count up minutes.
else
second_tens <= second_tens + 1;
end if;
else
second_ones <= second_ones + 1;
end if;
end if;
end if;
end process;
Minutes and hours can be counted analogously.
You have skipped a step. You are trying to think about code with just a worded problem statement. First step is to design the hardware by drawing a block diagram. Break the problem down into pieces.
Initial partitioning might be Seconds, Minutes, and Hours. If you are counting in BCD, it you may wish to partition it further digit by digit. Work out what your hardware is supposed to do. Draw a picture. Write code that describes what is in the picture.
At the end of the day, your RTL block diagram is your HDL flow chart.

How to implement a (pseudo) hardware random number generator

How do you implement a hardware random number generator in an HDL (verilog)?
What options need to be considered?
This question is following the self-answer format. Addition answers and updates are encouraged.
As noted in Morgan's answer this will only produce a single random bit. The number of bits in the LFSR only set how many values you get before the sequence repeats. If you want an N bit random number you have to run the LFSR for N cycles. However, if you want a new number every clock cycle the other option is to unroll the loop and predict what the number will be in N cycles. Repeating Morgan's example below, but to get a 5 bit number each cycle:
module fibonacci_lfsr_5bit(
input clk,
input rst_n,
output reg [4:0] data
);
reg [4:0] data_next;
always #* begin
data_next[4] = data[4]^data[1];
data_next[3] = data[3]^data[0];
data_next[2] = data[2]^data_next[4];
data_next[1] = data[1]^data_next[3];
data_next[0] = data[0]^data_next[2];
end
always #(posedge clk or negedge rst_n)
if(!rst_n)
data <= 5'h1f;
else
data <= data_next;
endmodule
Edit: Added a new version below which doesn't require you to do the math. Just put it in a loop and let the synthesis tool figure out the logic:
module fibonacci_lfsr_nbit
#(parameter BITS = 5)
(
input clk,
input rst_n,
output reg [4:0] data
);
reg [4:0] data_next;
always_comb begin
data_next = data;
repeat(BITS) begin
data_next = {(data_next[4]^data_next[1]), data_next[4:1]};
end
end
always_ff #(posedge clk or negedge reset) begin
if(!rst_n)
data <= 5'h1f;
else
data <= data_next;
end
end
endmodule
I would like to make the LFSR length parameterizable as well, but that is much more difficult since the feedback taps don't follow a simple pattern.
This is a TRNG (True random number generator) that works on an FPGA. It is basically an LFSR type structure without the flip flops, so it is a combinatorial loop that runs continuously. The signal oscillates chaotically, when you combine several of these modules and XOR bits you get a truly random bit, since the jitter from each combines. The maximum clock rate you can run this at depends on your FPGA, you should test the randomness with a testing suite like diehard, dieharder, STS or TestU01.
These are called Galois Ring Oscillators(GARO). There are other TRNGs which use less power and area, but they are tricker to operate and write, usually relying on tuning delays to make a flipflop go metastable.
module GARO (input stop,clk, reset, output random);
(* OPTIMIZE="OFF" *) //stop *xilinx* tools optimizing this away
wire [31:1] stage /* synthesis keep */; //stop *altera* tools optimizing this away
reg meta1, meta2;
assign random = meta2;
always#(posedge clk or negedge reset)
if(!reset)
begin
meta1 <= 1'b0;
meta2 <= 1'b0;
end
else if(clk)
begin
meta1 <= stage[1];
meta2 <= meta1;
end
assign stage[1] = ~&{stage[2] ^ stage[1],stop};
assign stage[2] = !stage[3];
assign stage[3] = !stage[4] ^ stage[1];
assign stage[4] = !stage[5] ^ stage[1];
assign stage[5] = !stage[6] ^ stage[1];
assign stage[6] = !stage[7] ^ stage[1];
assign stage[7] = !stage[8];
assign stage[8] = !stage[9] ^ stage[1];
assign stage[9] = !stage[10] ^ stage[1];
assign stage[10] = !stage[11];
assign stage[11] = !stage[12];
assign stage[12] = !stage[13] ^ stage[1];
assign stage[13] = !stage[14];
assign stage[14] = !stage[15] ^ stage[1];
assign stage[15] = !stage[16] ^ stage[1];
assign stage[16] = !stage[17] ^ stage[1];
assign stage[17] = !stage[18];
assign stage[18] = !stage[19];
assign stage[19] = !stage[20] ^ stage[1];
assign stage[20] = !stage[21] ^ stage[1];
assign stage[21] = !stage[22];
assign stage[22] = !stage[23];
assign stage[23] = !stage[24];
assign stage[24] = !stage[25];
assign stage[25] = !stage[26];
assign stage[26] = !stage[27] ^ stage[1];
assign stage[27] = !stage[28];
assign stage[28] = !stage[29];
assign stage[29] = !stage[30];
assign stage[30] = !stage[31];
assign stage[31] = !stage[1];
endmodule
An LFSR is often the first port of call. Implementation is relatively simple, a shift register with a number of terms XORd together to create the feedback term.
When considering the implementation of the LFSR, the bit width of the random number and the repeatability of the number need to be considered. With N bits a Maximal LFSR will have (2**N) - 1 states. All zero state can not be used with out additional hardware.
An example 4 bit LFSR with taps a bit 0 and bit 4:
module fibonacci_lfsr(
input clk,
input rst_n,
output [4:0] data
);
wire feedback = data[4] ^ data[1] ;
always #(posedge clk or negedge rst_n)
if (~rst_n)
data <= 4'hf;
else
data <= {data[3:0], feedback} ;
endmodule
Choosing tap points and finding out the sequence length (number of numbers before it repeats) can be found from this table.
For example a sequence of 17,820,000, 30 bits wide could use taps of :
0x20000029 => bits "100000000000000000000000101001"
0x2000005E => bits "100000000000000000000001011110"
0x20000089 => bits "100000000000000000000010001001"
The first would have a feedback term of:
feedback = data[29] ^ data[5] ^ data[3] ^ data[0];
If you are unsure of the order of the taps, remember that the MSB will always be a feedback point. The Last (tap) feedback point defines the effective length of the LFSR, after that it would just be a shift register and have no bearing on the feedback sequence.
If you needed a sequence of 69,273,666 you would have to implement a 31 bit LFSR and choose 30 bits for your random number.
LFSRs are a great way to create a 1-bit random number stream but if you are taking multiple consecutive bits that there is a correlation between values, it is the same number shifted plus dither bit. If the number is being used as a dither stream you may want to introduce a mapping layer, for example swap every other bit. Alternatively use an LFSR of different length or tap points for each bit.
Further Reading
Efficient Shift Registers, LFSR Counters, and Long Pseudo-Random Sequence Generators,
A Xilinx app note by Peter Alfke.
Linear Feedback Shift Registers in Virtex Devices,
A Xilinx app note by Maria George and Peter Alfke.

Resources