What does '1 mean in verilog? - verilog

I have a register with 4bits.
reg[3:0] a;
And I want to assign a single bit to it like
a <= '1;
Apparently it is not the same 1'b1 and 1.
I am new to verilog and not sure about its syntax.
Can anyone enlighten me please.

This sets all bits to 1, I believe.

Just to answer the original question,
To assign '1' to a[3:0], do one of the following (assuming you're in an always block):
a <= 4'b1; // binary 1 in 4 digits
a <= 4'h1; // hexadecimal 1 in 4 digits
a <= 4'd1; // decimal
a <= 4'b0001; // I prefer this syntax with explicit zero padding
Each of the above assignments can also explicitly specify the range of the signal:
a[3:0] <= 4'h1;
Note that the assignment <= could be replaced with = depending on your needs.

Related

Clean way to truncate result of addition or subtraction

When I do addition or subtraction in Verilog, some compilers emit warning.
// code example
logic [9 : 0] a, b, c;
always_ff #(posedge clk) begin
b <= a + 1;
c <= a - 1;
end
// warning example
Warning (13469): Verilog HDL assignment warning at xxx.sv(xxx): truncated value with size 11 to match size of target (10) File: xxx.sv Line: xxx
Warning (13469): Verilog HDL assignment warning at xxx.sv(xxx): truncated value with size 32 to match size of target (10) File: xxx.sv Line: xxx
I want to find clean way to remove these warnings. I tried two methods:
// method 1
b <= (a + 1)[9 : 0];
// method 2
logic [10 : 0] d;
d <= a + 1;
b <= d[9 : 0];
I thought the first method would compile, but it was invalid syntax in verilog.
Second method works, but it is too verbose and dirty.
Is there any other clean ways?
From IEEE Std 1364-2001.
Page 73:
Table 29—Bit lengths resulting from self-determined expressions:
Unsized constant number = Same as integer
Page 45:
NOTE Implementations may limit the maximum size of an integer variable, but they shall at least be 32 bits.
So the warnings you see come from trying to operate one unsized numeric constant (32 bits at least) with a sized variable (10 bits), so the synthesizer warns about the result may overflow.
So, just make sure all your operands have the same size:
Instead of:
// code example
logic [9 : 0] a, b, c;
always_ff #(posedge clk) begin
b <= a + 1;
c <= a - 1;
end
Do:
// code example
logic [9 : 0] a, b, c;
always_ff #(posedge clk) begin
b <= a + 10'd1;
c <= a - 10'd1;
end
1 id a 32-bit value. As a result the width of the expression is 32.
The way around is to use a sized value of '1', i.e.
b <= a + 1'b1;
c <= b - 1'b1;
This can potentially give you an 11-bit result. Carryon bit will be lost. At this point you can do some other tricks. I guess this is the most common one. Use a carry on bit.
logic con;
logic[9:0] a,b;
...
{con, a} <= b + 1'b1;
You can use a temp variable, as in your example.
In general, verilog standard does allow free truncation or extension of operand widths and no warning is required. Definitely in this case you can ignore the warning or turn it off. I have not seen simulators which would warn about it. Just certain rule in linting tools.
Use curley concatination braces
b <= {a + 1}[9 : 0];
or change the constant size (which defaults to 32-bits)
b <= a + 10'd1;

Unexpected behaviour using the ternary operator (Verilog)

In the following Verilog module, I'd like to understand why the blocking assignment using concatenation doesn't give the same result as the 2 commented out blocking assignments.
When I run the program on the FPGA, it gives the expected result with the 2 blocking assignments (the leds blink), but not with the blocking assignment using concatenation (the leds stay off).
Bonus points for answers pointing to the Verilog specification explaining what is at play here!
/* Every second, the set of leds that are lit will change */
module blinky(
input clk,
output [3:0] led
);
reg [3:0] count = 0;
reg [27:0] i = 0;
localparam [27:0] nTicksPerSecond = 100000000;
assign led = {count[3],count[2],count[1],count[0]};
always # (posedge(clk)) begin
// This works:
//count = i==nTicksPerSecond ? (count + 1) : count;
//i = i==nTicksPerSecond ? 0 : i+1;
// But this doesn't:
{count,i} = i==nTicksPerSecond ?
{count+1, 28'b0 } :
{count , i+1};
end
endmodule
PS: I use Vivado 2018.2
The reason is because the widths of count+1 and i+1 are both 32 bits. An unsized number is 32 bits wide (1800-2017 LRM section 5.7.1) and the width of the addition operator is the size of the largest operand (LRM section 11.6.1). To make your code work, add a proper size to your numeric literals
{count,i} = i==nTicksPerSecond ?
{count+4'd1, 28'b0 } :
{count , i+28'd1};
A simpler way to write this code is
always # (posedge clk)
if (i== nTicksPerSecond)
begin
count <= count + 1;
i <= 0;
end
else
begin
i <= i + 1;
end

Multiplication Issues in Verilog

I'm trying to take two 7-bit numbers and multiply them with Verilog. However, I seem to be running into trouble. The multiplication seems to work (producing an output of 1) when the results are between 0-9 decimal. However it appears that any result larger than 9 does not seem to produce an output of 1. Even though "Operand1" and "Operand2" are technically only 4-bits (0-9 decimal), I've tried switching them to 7-bit numbers to determine if that would solve the issues I'm encountering.
This particular module checks the answer provided by a user in binary through physical switches and returns a 0 if said answer is incorrect and a 1 if correct. All other operations (Addition, Subtraction and Division) work perfectly.
Here is my code:
module checkAnswer(OpSel, negFlag, Operand1, Operand2, usrAnswer, Correct);
input [1:0]OpSel;
input [6:0]Operand1, Operand2;
input negFlag;
input [6:0]usrAnswer;
output reg Correct;
always # (*)
case (OpSel)
2'b00:
if ((Operand1%10 + Operand2%10) == usrAnswer)
Correct = 1'b1;
else
Correct = 1'b0;
2'b01:
if ((negFlag && (Operand2 > Operand1) && ((Operand1%10 - Operand2%10) == -1*usrAnswer)) || ((Operand1 >= Operand2) && ((Operand1%10 - Operand2%10) == usrAnswer)))
Correct = 1'b1;
else
Correct = 1'b0;
2'b10:
if ((Operand1%10 * Operand2%10) == usrAnswer)
Correct = 1'b1;
else
Correct = 1'b0;
2'b11:
if ((Operand1%10 / Operand2%10) == (usrAnswer))
Correct = 1'b1;
else
Correct = 1'b0;
default: Correct = 1'b0;
endcase
endmodule
The problem is caused by operator precedence. Since % and * have the same precedence, your code executes as if parentheses were used like this:
((Operand1%10) * Operand2)%10
If you use 12 and 7, you get 4 instead of 14. To fix it, add more parentheses:
if (((Operand1%10) * (Operand2%10)) == usrAnswer)
Refer to IEEE 1800-2012, 11.3.2 Operator precedence

Take the sum of 3 adc data for 3 sampling

Hi everyone,
I am a newbie in programming FPGA by verilog language. At the present, I am trying to design the firmware to calculate the sum of adc data at 3 sampling. Firstly, I will explain about one adc at one sampling in my code. When you look at the code, you can see that with rising-edge of clkr clock and adcIfEnb == 1, the adc_data will get the value from adcIfData and this is the data for one sampling. In the next rising-edge of clkr clock and adcIfEnb == 1, this data is stored in iradcTrg. Finally, I will have the 3 data of adc_data for 3 sampling which are stored in iradcTrg and then I summarize 3 these data.
wire adcIfData[79:0];
reg
always #(posedge clkr) begin
if(adcIfEnb) begin
adc_data[9:0] <= adcIfData[9:0];
end
end
reg [29:0] iradcTrg;
reg [9:0] adcTrg;
always #(posedge clkr) begin
if (adcIfEnb) begin
iradcTrg[29:0] <= {adc_trg[19:10],adc_trg[9:0],adc_data[9:0]};
adcTrg[9:0] <= adc_trg[29:20] + adc_trg[19:10] + adc_trg[9:0];
end
end
However, there are 2 problems which I do not know how to solve.
Firstly, at the beginning time, when the first data of adc_data is stored at iradcTrg and adcTrg also take the sum. It means that adcTrg = 0 + 0 + first_adc_data but this sum need to be avoided.
Secondly, according to my design, I see that adc_data is serialized into iradcTrg. It means that the adc_data will be stored like this:
[1 2 3] 4 5 6 => 1 [2 3 4] 5 6=> 1 2 [3 4 5] 6
But in my case, I would like that the adc_data will be stored like this to get the sum
[1 2 3] 4 5 6 => 1 2 3 [4 5 6]
Therefore, how should I repair my code to get the result that I expected or are there any documents can help me in this case ?
To start: make sure your code is correctly indented when you put it on stackexchange. Secondly: I assume you have edited the code before posting it here because that code will not compile e.g. there is a floating 'reg' at the top and no module declaration.Thirdly: you have defined a wire adcIfData[79:0] I am going to assume you meant that to be [9:0].Forthly: You use variables which are not defined: adc_data, adc_trg.
Fifthly: I suggest you give your variables more meaningfull names like: gater_samples, sum_off_samples.
Now lets look at the core of the code. You want to take samples and shift them into a 30 bit register. There is no need to write "adc_trg[19:10],adc_trg[9:0]" adc_trg[19:0] will suffice. Also there is no need to put it in a different register beforehand. I would just use:
always #(posedge clkr)
if (adcIfEnb)
iradcTrg[29:0] <= {iradcTrg[19:0],adcIfData[9:0]};
As to your basic problem of gathering samples and not using the first two: all you have to do is add a counter which counts to three. Then you add the result on the third count. You will need a reset to give the counter a known value at startup but I don't see a reset signal. I always try to use minimal logic so I would make iradcTrg 20 bits wide to only store the intermediate result and at the count of three add it up with the latest sample. Saves another 10 registers. Here is some code. I wrote this without simulating or compiling. It is just a guide of how it all should look like.
reg [ 1:0] count;
reg [19:0] gather_samples;
reg [ 9:0] sum_of_samples;
reg sum_valid;
always #(posedge clkr)
begin
if (some_reset)
count <= 2'd0;
else
if (adcIfEnb)
begin
if (count==2'd2)
begin // third sample arriving, add it to the previous 2
sum_of_samples <= gather_samples[19:10] + gather_samples[9:0] + adcIfData;
count <= 2'd0;
else
begin // intermediate: gather samples
gather_samples <= {gather_samples[9:0],adcIfData};
count <= count + 2'd1;
end
sum_valid <= (count==2'd2);
end // if (adcIfEnb)
end // clocked
Your job will be much easier if you use a state machine. Here's a small (and incomplete) example of a state machine.
parameter FIRST_DATA=0, SECOND_DATA=1, THIRD_DATA=2, OUTPUT=3;
reg [2:0] current_state = FIRST_DATA;
reg [9:0] adc_data1;
reg [9:0] adc_data2;
reg [9:0] adc_data3;
reg [11:0] adc_data_sum;
always # (posedge clk)
begin
// TODO: use proper reset
case (current_state):
FIRST_DATA:
if(adcIfEnb):
current_state <= SECOND_DATA;
SECOND_DATA:
if(adcIfEnb):
current_state <= THIRD_DATA;
THIRD_DATA:
if(adcIfEnb):
current_state <= OUTPUT;
OUTPUT:
if(adcIfEnb):
current_state <= FIRST_DATA;
endcase
end
always # (negedge clk)
begin
if (current_state == FIRST_DATA && adcIfEnb)
adc_data1 <= adcIfData;
end
always # (negedge clk)
begin
if (current_state == SECOND_DATA && adcIfEnb)
adc_data2 <= adcIfData;
end
always # (negedge clk)
begin
if (current_state == THIRD_DATA && adcIfEnb)
adc_data3 <= adcIfData;
end
always # (negedge clk)
begin
if (current_state == OUTPUT)
adc_data_sum <= adc_data1 + adc_data2 + adc_data3;
end
Few comments first:
1) I don't know why do you introduce so many variables with strange names. You only need a adc_buffer and adc_sum. Is iradcTrg the same as adc_trg? Why is there an empty reg statement? Why adcIfData has 80 bits and you only use 8 LSB bits? I'm confused.
2) Since adc_sum will be a sum of 3 (adcTrg in your case), think about possible overflow. What should be the width of adc_sum if you want to add 3 10-bit numbers?
3) Shouldn't you reset your design to a known state using asynchronous or synchronous reset first?
You can use a 2 bit counter with async reset and a logic for wrapping back to 0:
reg [1:0] adc_buffer_counter_reg;
always #(posedge clkr or negedge rst_n) begin
if (!rst_n)
adc_buffer_counter_reg <= 2'd0;
else if (adcIfEnb) begin
if (adc_buffer_counter_reg == 2'd2) //trigger calc of the sum here
adc_buffer_counter_reg <= 2'd0;
else
adc_buffer_counter_reg <= adc_buffer_counter_reg + 2'd1;
end
You can use this counter to trigger a calculation of the sum every 3rd valid data.

Verilog Signed Multiplication "loses" the Signed Bit

I am writing a code which uses a multiplier module which returns weird answers when one of the inputs is a negative number. I am guessing this has to do with how Verilog treats signed numbers and the module is not storing the result properly in the 'reg signed out' decleration. All my input/output/wire/reg declarations are signed, so I am not sure what I am missing and what else I need to do to tell Verilog to take care of this. Sorry for the beginner question!
For example,
When X[0] is 1610 and Theta1[1] is -123, the result I am getting from the multiplier module is:
6914897148530
Here are the relevant parts of my code:
module mult(in1, in2, out, mult_start); // multiplication module
input signed [32-1:0] in1, in2;
input mult_start;
output signed [64-1:0] out;
reg signed [64-1:0] out;
always #(in1 or in2 or mult_start)
begin
if (mult_start)
begin
out <= (in1 * in2) & {64{1'b1}};
end
else
out <= out;
end
endmodule
module child_one (clk, rst_b, sig_start, Input_X, Input_Theta1)
// Internal Variables Memory
reg signed [`REG_LENGTH-1:0] Theta1 [0:217-1];
reg signed [`REG_LENGTH-1:0] X [0:216-1];
wire signed [`OUT_LENGTH-1:0] prod_1 [0:217-1];
reg signed [`OUT_LENGTH-1:0] prod_sum;
wire signed [`OUT_LENGTH-1:0] sig_result;
mult mult_001 (X[0], Theta1[1], prod_1[1], mult_start);
mult mult_002 (X[1], Theta1[2], prod_1[2], mult_start);
mult mult_003 (X[2], Theta1[3], prod_1[3], mult_start);
mult mult_004 (X[3], Theta1[4], prod_1[4], mult_start);
always #(posedge clk or negedge rst_b)
begin
if (sig_start == 1)
begin
if (state == 4'b0000)
begin
state <= 4'b0001; // initialize state variable to zero
k <= 0;
result_done <= 0;
index <= 0;
end
else if (state == 4'b0001) // Start Multiplication Operation
begin
k <= result_done ? 0 : k + 1;
result_done <= result_done ? 1 : (k == 10);
state <= result_done ? 4'b0010 : 4'b0001;
mult_start <= result_done ? 1'b1 : 1'b0;
//mult_start <= 1'b1;
//state <= 4'b0010;
end
else if (state == 4'b0010) // Stop Multiplication Operation
begin
k <= 0;
result_done <= 0;
mult_start <= 0;
state <= 4'b0011;
end
end
end
endmodule
Thanks,
Faisal.
Thanks for all the help and suggestions. Writing a separate testbench for the mult module helped arrive at a solution.
My issue was in the mult module. Since my inputs are 32 bits long, the mult output would be 32*2+1 = 65 bits long. My output port 'out' was only assigned to be 64 bits long which resulted in a sign issue when the answer was a negative number. Assigning it to be 65 bits long took care of my problem.
The issue is the & {64{1'b1}} part in the mult module. {64{1'b1}} is an unsigned subexpression. This causes in1 and in2 and to be treated as unsigned regardless of their declaration, and causes unsigned multiplication to be performed. The resulting bits assigned to out are then interpreted as signed again because of its declaration, but by then it's too late.
As you alluded to, the general Verilog signedness rule is that if any operand in a simple expression is unsigned, all operands in the expression are interpreted as unsigned, and thus the operators perform unsigned math. (There are many other nuances to the rules (e.g. relational operators), but they aren't applicable here.)
Note that you can't make {64{1'b1}} signed by changing it to {64{1'sb1}} because the result of the replication operator is always unsigned regardless of its operand. But you could wrap it in the $signed() system function, making the rest of the expression (the * and & steps) fully signed. Thus this would work correctly:
out <= (in1 * in2) & $signed({64{1'b1}});
But you really don't need to mask the result with that &. Regardless of the width of the inputs and the result of the multiplication, Verilog rules state that the final value of the RHS of the assignment will simply be truncated (discarding some MSBs) to the width of the LHS, if the RHS were wider. Thus masking with 64 ones is completely redundant.
To address the currently-accepted answer... It is not true that 65 bits are needed for 32x32 signed->signed multiplication. Only 64 bits are needed to handle even the most-extreme cases:
minimum result: -(2^31) * ((2^31) - 1) = -4611686016279904256 > -(2^63)
maximum result: ((2^31) - 1) * ((2^31) - 1) = 4611686014132420609 < (2^63) - 1
In general, for fully-signed multiplication of N bits by M bits, you only need N+M bits for the product (and N+M-1 would suffice if not for the single most-negative times most-negative case). This is also true for fully-unsigned multiplication. But if you were mixing signed and unsigned multiplicands/product (and using $signed() as needed to get Verilog to behave as desired), you would need an extra result bit in some cases (e.g. unsigned*unsigned->signed).

Resources