Keep specific bits from calculation - verilog

Is it possible to keep only the last X bits from a calculation like this?:
a_register <= some_addr - {some_addr[(width-1):limit],limit{1'b0}}
//can it be done in one line of code? Like:
//a_register <= some_addr - {some_addr[(width-1):limit],limit{1'b0}} [X:0]

You can assign to concatenated wires, with a temp variable for the LSBs which should make it clear to synthesis tools that those bits are not used and could be optimised away.
wire [4:0] temp;
assign {a_register, temp} = some_addr - {some_addr[(width-1):limit],limit{1'b0}};
or
reg [4:0] temp;
always #(posedge clk) begin
{a_register, temp} <= some_addr - {some_addr[(width-1):limit],limit{1'b0}};
end

IF you want to retain only the last N bits of a calculation, you need only make a_register size N. The assignment will take only the last N bits of the calculation. If you need a_register to be larger for some reason, you can always only select the last N bits of a_register and assign that the value:
a_register[X:0] <= some_addr - {some_addr[(width-1):limit],limit{1'b0}};
What you have currently does not work; but you can always use a temp value to store the result of the calculation and take [X:0] of that.
assign temp = some_addr - {some_addr[(width-1):limit],limit{1'b0}};
...
a_register <= temp[X:0];
(Though its not 1 line)

Related

Instantiate a module based on a condition in Verilog

I have a 1023 bit vector in Verilog. All I want to do is check if the ith bit is 1 and if it is 1 , I have to add 'i' to another variable .
In C , it would be something like :
int sum=0;
int i=0;
for(i=0;i<1023;i++) {
if(a[i]==1) {
sum=sum+i;
}
Of course , the addition that I am doing is over a Galois Field . So, I have a module called Galois_Field_Adder to do the computation .
So, my question now is how do I conditionally check if a specific bit is 1 and if so call my module to do that specific addition .
NOTE: The 1023 bit vector is declared as an input .
It's hard to answer your question without seeing your module, as we can't gage where you are in your Verilog. You always have to think of how your code translates in gates. If we want to translate your C code into synthesizable logic, we can take the same algorithm, go through each bit one after the other, and add to the sum depending on each bit. You would use something like this:
module gallois (
input wire clk,
input wire rst,
input wire [1022:0] a,
input wire a_valid,
output reg [18:0] sum,
output reg sum_valid
);
reg [9:0] cnt;
reg [1021:0] shift_a;
always #(posedge clk)
if (rst)
begin
sum[18:0] <= {19{1'bx}};
sum_valid <= 1'b0;
cnt[9:0] <= 10'd0;
shift_a[1021:0] <= {1022{1'bx}};
end
else
if (a_valid)
begin
sum[18:0] <= 19'd0;
sum_valid <= 1'b0;
cnt[9:0] <= 10'd1;
shift_a[1021:0] <= a[1022:1];
end
else if (cnt[9:0])
begin
if (cnt[9:0] == 10'd1022)
begin
sum_valid <= 1'b1;
cnt[9:0] <= 10'd0;
end
else
cnt[9:0] <= cnt[9:0] + 10'd1;
if (shift_a[0])
sum[18:0] <= sum[18:0] + cnt[9:0];
shift_a[1021:0] <= {1'bx, shift_a[1021:1]};
end
endmodule
You will get your result after 1023 clock cycles. This code needs to be modified depending on what goes around it, what interface you want etc...
Of importance here is that we use a shift register to test each bit, so that the logic adding your sum only takes shift_a[0], sum and cnt as an input.
Code based on the following would also work in simulation:
if (a[cnt[9:0])
sum[18:0] <= sum[18:0] + cnt[9:0];
but the logic adding to sum would in effect take all 1023 bits of a[] as an input. This would be quite hard to turn into actual lookup tables.
In simulation, you can also implement something very crude such as this:
reg [1022:0]a;
reg [9:0] sum;
integer i;
always #(a)
begin
sum[9:0] = 10'd0;
for (i=0; i < 1023; i=i+1)
if (a[i])
sum[9:0] = sum[9:0] + i;
end
If you were to try to synthesize this, sum would actually turn into a chunk of combinatorial logic, as the 'always' block doesn't rely on a clock. This code is in fact equivalent to this:
always #(a)
case(a):
1023'd0: sum[18:0] = 19'd0;
1023'd1: sum[18:0] = 19'd1;
1023'd2: sum[18:0] = 19'd3;
etc...
Needless to say that a lookup table with 1023 input bits is a VERY big memory...
Then if you want to improve your code, and use your FPGA as an FPGA and not like a CPU, you need to start thinking about parallelism, for instance working in parallel on different ranges of your input a. But this is another thread...

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.

Multiplying two 32 bit numbers using 32 bit carry look ahead adder

I have tried to write the code in Verilog to multiply two 32 bit binary numbers using a 32 bit carry look ahead adder but my program fails to compile. the generate if condition must be a constant expression error keeps on coming in Modelsim for the part 'if(store[0]==1)' and 'if(C[32]==1)'
This is the algorithm that I followed:
Begin Program
Multiplier = 32 bits
Multiplicand = 32 bits
Register = 64 bits
Put the multiplier in the least significant half and clear
the most significant half
For i = 1 to 32
Begin Loop
If the least significant bit of the 64-bit register
contains binary ‘1’
Begin If
Add the Multiplicand to the Most Significant
Half using the CLAA
Begin Adder
C[0 ] = ’0’
For j = 0 to 31
Begin Loop
Calculate Propagate P[j] = Multiplicand[j]^ Most Significant Half[j]
Calculate Generate G[j] =
Multiplicand[j]·Most Significant Half[j]
Calculate Carries C[i + 1] = G[i] + P[i] ·
C[i]
Calculate Sum S[i] = P[i] Å C[i]
End Loop
End Adder
Shift the 64-bit Register one bit to the right
throwing away the least significant bit
Else
Only Shift the 64-bit Register one bit to the
right throwing away the least significant bit
End If
End Loop
Register = Sum of Partial Products
End Program
Code:
module Multiplier_32(multiplier,multiplicand,store);
output store;
input [31:0]multiplier,multiplicand;
wire [63:0]store;
genvar i,j;
wire g=32;
wire [31:0]P,G,sum;
wire [32:0]C;
assign store[31:0]=multiplier;
generate for(i=0;i<32;i=i+1)
begin
if(store[0]==1)
begin
assign C[0]=0;
for(j=0;j<32;j=j+1)
begin
assign P[j]= multiplicand[j]^store[g];
assign G[j]=multiplicand[j]&store[g];
assign C[j+1]=G[i]|(P[i]&C[j]);
assign sum[j]=P[i]^C[j];
assign g=g-1;
end
assign store[63:32]=sum[31:0];
if(C[32]==1)
begin
assign store[62:0]=store[63:1];
assign store[63]=1;
end
else
begin
assign store[62:0]=store[63:1];
assign store[63]=0;
end
end
else
begin
assign store[62:0]=store[63:1];
assign store[63]=0;
end
end
endgenerate
endmodule
A generate block is evaluated at compile/elaboration time. They are used to construct hardware from patterns and not to evaluate logic. The value of store[0], C[32], and all other signals are unknown at this time. The only know values are parameters and genvars.
In this case, a combinational block (always #*) will fulfill your functionality requirements. Replace all your wire with reg, but all your assignments inside a always #*, and remove all the assign keywords (assign should not be used inside an always block).
module Multiplier_32(
input [31:0] multiplier, multiplicand,
output reg [63:0] store
);
integer i,j;
integer g;
reg [31:0] P,G,sum;
reg [32:0] C;
always #* begin
g = 32;
store[31:0]=multiplier;
for(i=0;i<32;i=i+1) begin
// your code here, do not use 'assign'
end
end
endmodule

Verilog Register to output

I am working with an Altera DE2 development board and I want to read an input in on the switches. This is stored in registers. Based on a counter these registers are incremented. The registers are then supposed to be output to the Seven Segment Displays thought a B2D converter. But I can not pass a register to a function.
wire [26:0] Q,Q2,Q3,Q4;
wire [3:0] one,two,three,four;
reg SecInc,MinInc,HrInc;
reg [3:0] M1,M2,H1,H2;
assign one = SW[3:0];
assign two = SW[7:4];
assign three = SW[11:8];
assign four = SW[15:12];
always begin
M1 = SW[3:0];
M2 = SW[7:4];
H1 = SW[11:8];
H2 = SW[15:12];
end
This is how I get and store the inputs. They come from the switches which we use as a binary representation on Hours and Minutes.
Based on a counter we increment a minute or an hour register.
//increment seconds from 0 to 60
counter seconds (SecInc,KEY[0],Q2);
defparam seconds.n = 8;
defparam seconds.mod = 60;
always # (negedge CLOCK_50) begin
if (Q2 >= 60) begin
MinInc = 1;
M1 <= M1 + 1'b1;
if(M1 >= 9) begin
M1 <= 0;
M2 <= M2 + 1'b1;
end
end else begin
MinInc = 0;
end
end
We want to display the result on the SSD's.
hex(M1,HEX4);
hex(M2,HEX5);
hex(H1,HEX6);
hex(H2,HEX7);
Here in lies the problem. This is not allowed in verilog. I need a way to send my registers to a function which displays numbers from 0 to 9 using some B2D conversion.
I will say I have never had a formal intro to verilog before and I have tried all I can think to do. I even tried to make a new module in which I would pass one,two,three,four and have the module increment them, like it does with Q2 for the counter I have shown. Any suggestions or help is greatly appreciated!
As requested here is the hex module:
module hex(BIN, SSD);
input [15:0] BIN;
output reg [0:6] SSD;
always begin
case(BIN)
0:SSD=7'b0000001;
1:SSD=7'b1001111;
2:SSD=7'b0010010;
3:SSD=7'b0000110;
4:SSD=7'b1001100;
5:SSD=7'b0100100;
6:SSD=7'b0100000;
7:SSD=7'b0001111;
8:SSD=7'b0000000;
9:SSD=7'b0001100;
endcase
end
endmodule
Thank you in advance!
Your hex module is not a function, it is a module and therefore must be instantiated with an instance name like this:
hex digit0(.BIN(M1), .SSD(HEX4));
hex digit1(.BIN(M2), .SSD(HEX5));
hex digit2(.BIN(H1), .SSD(HEX6));
hex digit3(.BIN(H2), .SSD(HEX7));
In addition to nguthrie being correct, that you need to instantiate your hex converter as a module, you drive M1 from a race condition in your always block. Non-blocking assignments will evaluate simultaneously within a block (or essentially simultaneously). This is not a program, where things happen in order. What might work better is:
always # (negedge CLOCK_50) begin
if (Q2 >= 60) begin
MinInc = 1;
if (M1 < 9) begin
M1 <= M1 + 1'b1;
end else begin
M1 <= 0;
M2 <= M2 + 1'b1;
end
end else begin
MinInc = 0;
end
end
You will also potentially get unexpected results from your blocking assignments to MinInc, but since I don't see where this is read it's hard to know what will happen.
Read up on blocking (=) vs non-blocking (<=) assignments in Verilog. It's one of the trickiest concepts of the language, and misuse of the two operations is the cause of 90% of the most dastardly bugs I've ever seen.
EDIT: In re-reading your question, it seems that you're trying to drive M1-4 from at least three places. You really can't have a continuous always begin block and a clocked (always # (negedge clock) begin) driving the same register. This will send your compiler into a tantrum.

Issue with Logic in Verilog

I'm trying to write a multiplier based on a design. It consists of two 16-bit inputs and the a single adder is used to calculate the partial product. The LSB of one input is AND'ed with the 16 bits of the other input and the output of the AND gate is repetitively added to the previous output. The Verilog code for it is below, but I seem to be having trouble with getting the outputs to work.
module datapath(output reg [31:15]p_high,
output reg [14:0]p_low,
input [15:0]x, y,
input clk); // reset, start, x_ce, y_ce, y_load_en, p_reset,
//output done);
reg [15:0]q0;
reg [15:0]q1;
reg [15:0]and_output;
reg [16:0]sum, prev_sum;
reg d_in;
reg [3:0] count_er;
initial
begin
count_er <= 0;
sum <= 17'b0;
prev_sum <= 17'b0;
end
always#(posedge clk)
begin
q0 <= y;
q1 <= x;
and_output <= q0[count_er] & q1;
sum <= and_output + prev_sum;
prev_sum <= sum;
p_high <= sum;
d_in <= p_high[15];
p_low[14] <= d_in;
p_low <= p_low >> 1;
count_er <= count_er + 1;
end
endmodule
I created a test bench to test the circuit and the first problem I see is that, the AND operation doesn't work as I want it to. The 16-bits of the x-operand are and'ed with the LSB of the y-operand. The y-operand is shifted by one bit after every clock cycle and the final product is calculated by successively adding the partial products.
However, I am having trouble starting from the sum and prev_sum lines and their outputs are being displayed as xxxxxxxxxxxx.
You don't seem to be properly resetting all the signals you need to, or you seem to be confusing the way that nonblocking assignments work.
After initial begin:
sum is 0
prev_sum is 0
and_output is X
After first positive edge:
sum is X, because and_output is X, and X+0 returns X. At this point sum stays X forever, because X + something is always X.
You're creating a register for almost every signal in your design, which means that none of your signals update immediately. You need to make a distinction between the signals that you want to register, and the signals that are just combinational terms. Let the registers update with nonblocking statements on the posedge clock, and let the combinational terms update immediately by placing them in an always #* block.
I don't know the algorithm that you're trying to use, so I can't say which lines should be which, but I really doubt that you intend for it to take one clock cycle for x/y to propagate to q0/q1, another cycle for q to propagate to and_output, and yet another clock cycle to propogate from and_output to sum.
Comments on updated code:
Combinational blocks should use blocking assignments, not nonblocking assignments. Use = instead of <= inside the always #* block.
sum <= and_output + sum; looks wrong, It should be sum = and_output + p_high[31:16] according to your picture.
You're assigning p_low[14] twice here. Make the second statement explicitly set bits [13:0] only:
p_low[14] <= d_in;
p_low[13:0] <= p_low >> 1;
You are mixing blocking and nonblocking assignments in the same sequential always block, which can cause unexpected results:
d_in <= p_high[15];
p_low[14] = d_in;

Resources