bit vector range selection with runtime value in system verilog - logic

Let's say I have a vector value[6:0] and an input vector input[3:0]. The problem is I want to set a number of bit in value vector to 1 base on value of input, e.g.:
input = 0011 (3 in dec) then value = 000111 (set 3 bits to 1)
input = 0101 (5 in dec) then value = 011111 (set 5 bits to 1)
As we can do this easy only when the value in constant, but here it is run-time change. Any ideas on solve this?

There's no need to select a range here.
wire [3:0] input;
wire [7:0] shifted;
wire [6:0] value; //This can only hold 0 to 7
//Assign 2^input then subtract 1
assign shifted = 1'b1 << input;
assign value = shifted - 1;

This could be as simple as this:
wire [3:0] input;
wire [31:0] constant_value = 32'h0000_FFFF;
wire [15:0] output;
assign output = constant_value[ input +: 16 ];
Note "+:" range selection.

Related

Quartus 2 verliog using curly craces to set particular bits

Hi I am new to verilog and I try to set some particular bits from one reg variable to another reg but it didn't work for me. what am ı doing wrong?
reg [31:0] a;
reg [31:0] b;
initial begin
a =32'b0;
b =32'b1;
$display("current value of a = %32b ",a);
a ={b[5:0]};
$display("value of a %32b ",a);
#10 $finish;
end
bit of a from a[0] to a[5] should be 1 but only a[0] became 1
In you code b = 32'b1 yields {31{1'b0},1'b1}, so only b[0] is equal to one.
In SystemVerilog (check: IEEE1800-2012, 5.7.1 Integer literal constants) you can use automatic left padding of constant literal numbers using a single-bit value, i.e. b = '1 to set all bits of b to one.
Using Verilog, simply assign another value to b (i.e. b = 32'b11111) or change your code to following:
a[4:0] = {5{b[0]}}

Verilog Code:FIR Filter= RAM modeling for reading coefficients values from file .. not showing simulation results

In verilog for only this line of code its showing simulation output
1)
#( parameter width=1, length=16 )
(* ram_style = "block" *)
reg [(width)-1:0] mem[(1<<length)-1:0];
2)but for the below line it is not showing simulation output
#( parameter width=8, length=16 )
(* ram_style = "block" *)
reg [(2*width)-1:0] mem[(1<<length)-1:0];
Explain why 2nd set of code is not showing simulation results?
actually I want store 8 bits of min 65535 filter coefficients.. I want to read and write ..
please guide me in this...
A model of a RAM might look some thing like the code below, to write to it it is just a mater of sequencing the wr_addr, wr_data and wr_en.
module ram #(
parameter DATA_W = 8,
parameter DATA_D = 256
) (
input clk,
input rst_an,
input [0:$clog2(DATA_D)] rd_addr,
input [0:$clog2(DATA_D)] wr_addr,
input [0:DATA_W-1] wr_data,
input wr_en,
output [0:DATA_W-1] rd_data
);
reg [0:DATA_W-1] ram_data [0:DATA_D-1];
//READ
always #* begin
rd_data = ram_data[rd_addr];
end
//WRITE
always #(posedge clk, negedge rst_an) begin
if (~rst_an) begin
for(int i = 0; i<DATA_D ; i++) begin
ram_data[i] <= 'b0 ;
end
end
else begin
if (wr_en) begin
ram_data[wr_addr] <= wr_data ;
end
end
end
for(int i = 0; i<DATA_D ; i++) is system verilog syntax.
for plain verilog declare integer i then replace the for loop with :
for(i = 0; i<DATA_D ; i=1+1)
clog2 : is used to get the address width required for the given depth.
If you want a depth of 4, you need 2 bits to address it. Depth of 16, 4 bits to address, ie
log2( 4) => 2
log2(16) => 4
If you use non-powers of two you want to round up or ceiling
log2(5) => 2.32192809489
clog2(5) => 3
Therefore clog2 is very useful to get the required addressing width from the depth of the RAM.

add and shift in verilog

Here's my verilog code about add and shift multiplying
when I compile and Initialze and adding the inputs and outputs to get waveforms and simulating them, I dont see any results, everything is z... what is the problem?
module multi(a, b, ans);
input [3:0] a;
input [3:0] b;
output reg [15:0] ans;
reg [15:0] aa;
reg [15:0] bb;
reg [15:0] tmp=0;
reg flag = 1'b1;
always #( a, b)
begin
aa = a;
bb = b;
while ( flag == 1'b1 )
begin
if( bb[0] == 1'b1 )
tmp = tmp + aa;
aa = aa << 1;
bb = bb >> 1;
if ( bb==0 )
flag = 1'b0;
end
ans = tmp;
end
endmodule
There are a number of things that look strange with this code.
First is that you have no clock input, but are attempting to do everything with combinatorial logic.
Second is that setting flag to 1 in the reg statement will mean that your module is only capable of doing a single multiplication. By the way, it is more normal (especially for ASIC design) to use a reset signal than use this initialisation in a reg line.
Third is that a 4 bit number times a 4 bit number will result in an 8bit answer, not 16bit.
In any case, unless you are working at very high speeds you should be able to perform a multiply in a single cycle.
Here are a couple of ways of writing this code more naturally:
Combinatorial Style
module multi(a, b, ans);
input [3:0] a;
input [3:0] b;
output reg [7:0] ans;
always #(*)
begin
ans = a * b;
end
endmodule
Clocked style
module multi(clk, a, b, ans);
input [3:0] a;
input [3:0] b;
output reg [7:0] ans;
always #(posedge clk)
begin
ans <= a * b;
end
endmodule
Your input is 4 bits wide and your assigning to a 16 bit variable, the top 12 bits are unassigned ie x.
input [3:0] a;
reg [15:0] aa;
//...
aa = a;
To assign all bits of aa try some thing like:
aa = {12'b0, a};
//{} is bit concatenation
Or to sign extend a to 16 bits, repeat the MSB 12 times using {width{value}} replication:
aa = {{12{a[3]}}, a};

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.

Splitting a bit array in Verilog

I am designing a basic AES algorithm on verilog, and I need to split a 128 bits array into 16 parts each one of 8 bits.
For example (basic 8 bit example), if I receive 10111011 I need to generate 4 outputs 10 11 10 11
Retrieving bytes from an array is straight forward:
module huge_array (
input [128-1:0] data
);
wire [7:0] first_byte,
assign first_byte = data[7:0];
wire [7:0] second_byte,
assign second_byte = data[8*2-1:8*1];
endmodule
It would be much easier if the data was formatted into a memory.
module huge_array2 (
input [7:0] data [0:16]
);
wire [7:0] first_byte,
assign first_byte = data[0];
wire [7:0] second_byte,
assign second_byte = data[1];
endmodule
A double packed array works:
reg [127:0] in;
wire [15:0] [7:0] out_1 = in; // msb in entry 15
wire [0:15] [7:0] out_2 = in; // msb in entry 0
If only one byte is needed to be read at a time, it can be done Verilog-2001 or SystemVerilog as:
reg [127:0] in;
reg [3:0] idx;
wire [7:0] out = in[8*idx +: 8];

Resources