Quartus 2 verliog using curly craces to set particular bits - set

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]}}

Related

Why does this error in indexing BCD adder appear?

I am not sure, what exactly the error is. I think, my indexing in the for-loop is not Verilog-compatible, but I might be wrong.
Is it allowed to index like this (a[(4*i)+3:4*i]) in a for-loop just like in C/C++?
Here is a piece of my code, so the for-loop would make more sense
module testing(
input [399:0] a, b,
input cin,
output reg cout,
output reg [399:0] sum );
// bcd needs 4 bits + 1-bit carry --> 5 bits [4:0]
reg [4:0] temp_1;
always #(*) begin
for (int i = 0; i < 100; i++) begin
if (i == 0) begin // taking care of cin so the rest of the loop works smoothly
temp_1[4:0] = a[3:0] + b[3:0] + cin;
sum[3:0] = temp_1[3:0];
cout = temp_1[4];
end
else begin
temp_1[4:0] = a[(4*i)+3:4*i] + b[(4*i)+3:4*i] + cout;
sum[(4*i)+3:4*i] = temp_1[3:0];
cout = temp_1[4];
end
end
end
endmodule
This might seem obvious. I'm doing the exercises from:
HDLBits and got stuck on this one in particular for a long time (This solution isn't the one intended for the exercise).
Error messages Quartus:
Error (10734): Verilog HDL error at testing.v(46): i is not a constant File: ../testing.v Line: 46
Error (10734): Verilog HDL error at testing.v(47): i is not a constant File: ../testing.v Line: 47
But I tried the same way in indexing and got the same error
The error appears because Verilog does not allow variables at both indices of a part select (bus slice indexes).
The most dynamic thing that can be done involves the indexed part select.
Here is a related but not duplicate What is `+:` and `-:`? SO question.
Variations of this question are common on SO and other programmable logic design forums.
I took your example and used the -: operator rather than the : and changed the RHS of this to a constant. This version compiles.
module testing(
input [399:0] a, b,
input cin,
output reg cout,
output reg [399:0] sum );
// bcd needs 4 bits + 1-bit carry --> 5 bits [4:0]
reg [4:0] temp_1;
always #(*) begin
for (int i = 0; i < 100; i++) begin
if (i == 0) begin // taking care of cin so the rest of the loop works smoothly
temp_1[4:0] = a[3:0] + b[3:0] + cin;
sum[3:0] = temp_1[3:0];
cout = temp_1[4];
end
else begin
temp_1[4:0] = a[(4*i)+3-:4] + b[(4*i)+3-:4] + cout;
sum[(4*i)+3-:4] = temp_1[3:0];
cout = temp_1[4];
end
end
end
endmodule
The code will not behave as you wanted it to using the indexed part select.
You can use other operators that are more dynamic to create the behavior you need.
For example shifting, and masking.
Recommend you research what others have done, then ask again if it still is not clear.

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};

Verilog two dimensional array syntax

I would like to instantiate an array of registers, and declare them all according to a certain function. This is for a multiplier block that I'm hoping to construct.
The code I'm working with is below, but this is the line that the compiler does not appreciate:
q[i][7:0] = {8{a[i]}} & b[7:0];
As the code is written out, I hope to make the registers q[0],q[1],....q[7] all store the 8-bit value define by the RHS above. Can anyone tell me what would be the proper way to do this?
Entire code:
`timescale 1ns / 1ps
module multiplier_2(
input [7:0] A,
input [7:0] B,
output reg [15:0] P,
input start,
output stop
);
reg [7:0] q[7:0];
reg P = 0;
//create 8 bit vectors q[i]
genvar i;
generate
for (i = 0; i < 8;i = i+1)
begin: loop
q[i][7:0] = {8{a[i]}} & b[7:0];
end
endgenerate
always # (*)
begin
if (start == 1'b1)
begin
for (i = 0; i < 8; i = i+1)
begin
P = P + (q[i] << i);
end
end
end
endmodule
EDIT: this code also doesn't work:
`timescale 1ns / 1ps
module multiplier_2(
input [7:0] a,
input [7:0] b,
output reg [15:0] P = 16'd0,
input start,
output stop
);
reg [7:0] q[7:0];
//create 8 bit vectors q[i]
genvar i;
generate
always begin
for (i = 0; i < 8;i = i+1)
begin: loop
q[i] = {8{a[i]}} & b[7:0];
end
end
endgenerate
always # (*)
begin
stop = 1'b0;
if (start == 1'b1)
begin
for (i = 0; i < 8; i = i+1)
begin
P = P + (q[i] << i);
end
end
stop = 1'b1;
end
endmodule
Error message:
"Line 16: Procedural assignment to a non-register i is not permitted, left-hand side should be reg/integer/time/genvar"
I do not think this require a generate statement. A standard for loop will work:
reg [7:0] q [0:7];
integer i;
always #* begin
for (i = 0; i < 8; i=i+1) begin: loop
q[i] = {8{a[i]}} & b[7:0];
end
end
Beware of what hardware you are implying though. For loops like generate statements imply parallel hardware.
NB: it is more common to list memories with the depth from 0 to x ie: reg [7:0] q [0:7];
You've got all sorts of issues here. First off, you're getting confused about what a generate statement is, and what you're trying to generate. Are you (1) trying to generate a single always block, which must contain sequential/procedural code, or are you (2) trying to generate/replicate 8 continuous assignments?
You're presumably not doing (1), since there's no point in generating a single always block; the generate is redundant. That leaves (2). So, get rid of the always begin after the generate. The i in your loop is now the 'genvar', or generation variable, and you're replicating 8 assignments; so far, so good. Get rid of the begin:loop and end; you're replicating a single statement, so they're pointless verbiage.
Next problem: the generate loop is now creating concurrent, or parallel, statements; in Verilog-speak, they're module-level statements. They means that they must be continuous assignments, ie they must have an assign in front of them, and not just ordinary procedural assignments, as you've written them. That also means that q must be declared as a wire, and not a reg. There's no good reason for this; it's just how Verilog is.
You now have a second always block, which is a concurrent (module-level) statement, which must contain sequential/procedural code. The i you're referring to in this block is the original genvar, which doesn't work. A genvar can only be used in specific generation-related circumstances; this isn't inside a generate, and you need an ordinary variable here as your index. you can do this by naming your outer begin/end, and declaring a variable inside it, or any other way. You'll now find out that you're creating a procedural assignment to net stop; this is illegal, so change stop's declaration to a reg. This should be enough to get your code to compile.
BTW, #(*) is verbose and unnecessary, and has historically confused at least one tool. #* is more concise.
You've got other issues. Your second always contains a loop. It looks like it might be logically correct, but your synthesiser has to unroll this, and carry out 8 additions, and set stop. This isn't going to work in real life. Think about making these additions concurrent and putting them in a generate, or creating a clocked pipeline, and some more robust (clocked) way of creating stop.

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.

bit vector range selection with runtime value in system verilog

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.

Resources