In Verilog, counting and outputting the number of 1's in an 8bit input? - verilog

What I am trying to do in my mind is take 8 1-bit inputs and count the 1's. Then represent those 1's.
01010111 should output 0101 (There are five 1's from input)
module 8to4 (in,out,hold,clk,reset);
input [7:0] in; //1 bit inputs
reg [7:0] hold; //possible use for case statement
output [3:0] out; //Shows the count of bits
always #(clk)
begin
out = in[0] + in[1] + in[2] + in[3] + in[4] + in[5] + in[6] + in[7]; //Adds the inputs from testbench and outputs it
end
endmodule
Questions:
Is that the proper way to have 8 1-bit inputs? Or do I need to declare each variable as one bit ex: input A,B,C,D,E,F,G,H;
If my above code is close to being correct, is that the proper way to get out to display the count of 1's? Would I need a case statement?
I'm really new to verilog, so I don't even want to think about a test bench yet.

The way you wrote it is probably the better way of writing it because it makes it easier to parameterize the number of bits. But technically, you have one 8-bit input.
module 8to4 #(parameter WIDTH=8) (input [WIDTH-1:0] in,
output reg [3:0] out,hold,
input clk,reset);
reg [WIDTH-1:0] temp;
integer ii;
always #(clk)
begin
temp = 0;
for(ii=0; ii<WIDTH; i = i + 1)
temp = temp + in[ii];
out <= temp;
end
endmodule

Logically the code is proper.
However you can improve it like the following.
Make out as a reg, because you are using it in a procedural assignment.
Usage of reset. Ideally any code should have reset state, which is missing in your code.
Declare the direction (input/output) for hold, clk & reset port, which is currently not specified.
As dave mentioned, you can use parameters for your code.

Related

what will be a good way to write 10bits decoder?

I am trying to write a 10 bits binary to thermal decoder.
For a 4 bits decoder, it is relative straightforward as shown below. However, for 10 bits, is there a smarter way to do it instead of write 1000 line code.
module decoder(in,out);
input [3:0] in;
output [15:0] out;
// input enable;
reg [15:0] out;
always #(in) begin
casez(in)
4'h1: out=16'b0000000000000001;
4'h2: out=16'b0000000000000011;
4'h3: out=16'b0000000000000111;
4'h4: out=16'b0000000000001111;
4'h5: out=16'b0000000000011111;
4'h6: out=16'b0000000000111111;
4'h7: out=16'b0000000001111111;
4'h8: out=16'b0000000011111111;
4'h9: out=16'b0000000111111111;
4'hA: out=16'b0000001111111111;
4'hB: out=16'b0000011111111111;
4'hC: out=16'b0000111111111111;
4'hD: out=16'b0001111111111111;
4'hE: out=16'b0011111111111111;
4'hF: out=16'b0111111111111111;
default: out=16'h0000;
endcase
end
endmodule
Yes, you could make this module fully parametrizable by using an unrollable for-loop. This loop would check for each bit of the out signal, if the loop-index is still smaller than the binary input signal.
The code would look like this:
module decoder #(
parameter IN_W = 10,
parameter OUT_W = 1 << IN_W
)
(
input [IN_W-1:0] in,
output reg [OUT_W-1:0] out
);
integer i;
always #* begin
// Use an unrollable loop.
for (i = 0; i < OUT_W; i++) begin
// (in < i) returns a 1-bit value
out[i] = (in < i);
end
end
endmodule
As you probably noticed, I also changed the way the ports are declared. In Verilog 2001—and also in more recent (System)Verilog versions—the port list and port declaration may be combined. This newer syntax, also known as ANSI-style, has the benefit that you don't need to add as much boilerplate code.

Bit by bit comparison between two variables in Verilog

Currently, I am beginning to write the firmware by Verilog for one idea. It is comparing bit by bit between two variables and then using one binary counter to count the number of different bits.
For example:
I have two variables in verilog
A : 8'b00100001;
B : 8'b01000000;
Then I give the condition to compare bit by bit between two variables. If there is difference between 1 bit of A and 1 bit of B at same bit position, binary counter will count.
This is my verilog code:
module BERT_test(
input CLK,
input RST,
input [7:0] SIG_IN,
input [7:0] SIG_OUT,
output [7:0] NUM_ERR
);
integer i;
reg[7:0] sign_in;
reg[7:0] sign_out;
always #(posedge CLK) begin
sign_in[7:0] <= SIG_IN[7:0];
sign_out[7:0] <= SIG_OUT[7:0];
end
reg [15:0] bit_err;
// Combinational Logic
always #* begin
bit_err = 8'b0;
for (i=0;i<8;i=i+1) begin
if (sign_in[i] == sign_out[i]) begin
bit_err = bit_err + 8'b0;
end else begin
bit_err = bit_err + 8'b1;
end
end
assign NUM_ERR = bit_err;
end
endmodule
Then I had a mistake
Reference to vector wire 'NUM_ERR' is not a legal reg or variable lvalue
I do not know how to solve this problem. Are there any solutions for this problem or how I need to modify my firmware, please suggest me.
You are driving NUM_ERR (a net) from an always block. It is not permitted to drive nets from always blocks (or initial blocks). You need to move this line:
assign NUM_ERR = bit_err;
outside the always block.
You should not use an assign statement inside an always block. This is legal but is deprecated and means something weird. If you have included this line inside the always block by mistake, then indenting you code properly would have shown it up.
You have an assign WITHIN an always block. Move it outside.
Adding zero to bit error if the bits are the same is superfluous.
if (sign_in[i] != sign_out[i])
bit_err = bit_err + 8'b1;
Also bit error is 16 bits so it is not wrong to add 8'b1 but misleading.

exiting for loop inside generate statement

I am trying using infinite for loop inside generate statement. But the problem is I cannot stop it or exit it using some condition. I used "disable" and "break". Both don't work.
It shows an error :
unexpected token: 'disable'
Please help me solve this problem or suggest an alternative to it. Here is my Verilog code:
module top(a1,a3,wj,d4,d10,d2,dc,dtot);
input [11:0]a1,a3,wj;
input [3:0]d4;
input [9:0]d10;
input [1:0]d2;
input [25:0]dc;
output reg[25:0]dtot;
reg [25:0]dt,error;
reg [11:0]alpha1,alpha3;
genvar i;
generate
for (i=1;i>0;i=i+1-1)begin:test
assign a1[11:0]=alpha1[11:0];
assign a3[11:0]=alpha3[11:0];
calb_top t1(a1,a3,wj,d4,d10,d2,dc,dt,error,alpha1,alpha3);
if(error==26'b00000000000000000000000000)begin
disable test;
//break;
end
end
endgenerate
assign dtot=dt;
endmodule
Verilog generate block are used to describe physical hardware. As such, an inifinite loop in a generate block will require infinite resources.
Any for loop inside a generate statement must be of a fixed and finite size that can be determined during synthesis.
Remember that HDL is not executed sequentially, but describes connections between physical circuits. Since it appears that you only require one instance of the calb_top module, you don't require either the generate block or the for loop.
Edit:
Since you're intending to perform an iterative process, you have two options, as Greg pointed out in his comment below - you can either instantiate a fixed number of calb_top blocks (since an infinite number would require an infinite amount of space) or to re-use the same block some number of times.
Here are some samples. I've haven't sim'd or synthesized them, but they're logically correct.
N-Block solution
module top(a1,a3,wj,d4,d10,d2,dc,dtot,clock,done);
parameter NUM_BLOCKS = 10;
input [11:0]a1,a3,wj;
input [3:0]d4;
input [9:0]d10;
input [1:0]d2;
input [25:0]dc;
output [25:0]dtot;
wire [11:0] a1s [NUM_BLOCKS:0];
wire [11:0] a3s [NUM_BLOCKS:0];
wire [25:0] dt [NUM_BLOCKS-1:0];
wire [25:0] error [NUM_BLOCKS-1:0];
assign a1s[0]=a1;
assign a3s[0]=a3;
genvar i;
generate
for (i=0;i<NUM_BLOCKS;i=i+1)begin:test
calb_top t1(a1s[i],a3s[i],wj,d4,d10,d2,dc,dt[i],error[i],a1s[i+1],a3s[i+1]);
end
endgenerate
assign dtot=dt[NUM_BLOCKS-1];
endmodule
This links together a number of calb_top blocks equal to NUM_BLOCKS, then outputs the result of the final block to dtot. This doesn't do any checks on the error, so you may want to put in your own code to check error[NUM_BLOCKS-1] (the error of the final calb_top).
Single-Block solution:
module top(clock,start,a1,a3,wj,d4,d10,d2,dc,dtot);
input clock;
input start;
input [11:0]a1,a3,wj;
input [3:0]d4;
input [9:0]d10;
input [1:0]d2;
input [25:0]dc;
output reg[25:0]dtot;
wire [25:0]dt,error;
reg [11:0] a1in, a3in;
wire [11:0] alpha1,alpha3;
calb_top t1(a1in,a3in,wj,d4,d10,d2,dc,dt,error,alpha1,alpha3);
always #(posedge clock)
begin
if (start)
begin
a1in <= a1;
a3in <= a3;
end
else
begin
a1in <= alpha1;
a3in <= alpha3;
end
end
always #(posedge clock)
if (start)
dtot <= 0;
else if (error == 0)
dtot <= dt;
else
dtot <= dtot;
endmodule
Each clock cycle, we run one pass through calb_top. If start is 1, then a1 and a3 are used as inputs. Otherwise, the previous outputs alpha1 and alpha3 are used. When error is 0, then dtot is set. Note that I've added clock and start to the port list.

What is the improve way to multiplying by 15?

I'm trying to implement as follows to multiplying by 15.
module mul15(
output [10:0] result,
input [3:0] a
);
assign result = a*15;
endmodule
But is there any improve way to multiplying to a by 15?
I think there are 2 ways like this
1.result = a<<4 -1;
2.result = {a,3'b1111_1111};
Ans I think the best way is 2.
but I'm not sure also with aspect to synthesis.
update:
What if I am multiplying 0 at {a,3'b1111_1111}? This is 255 not 0.
Does anyone know the best way?
Update
How about this way?
Case1
result = {a,8'b0}+ {a,7'b0}+ {a,6'b0}+ {a,5'b0}+ {a,4'b0}+ {a,7'b0}+ {a,3'b0}+ {a,2'b0}+ {a,1'b0}+ a;
But it looks 8 adder used.
Case2
result = a<<8 -1
I'm not sure what is the best way else.
There is always a*16 - a. Static multiplications of power of 2 are basically free in hardware; it is just hard-coded 0s to the LSB. So you just need one 11-bit full-subtracter, which is a full adder and some inverters.
other forms:
result = a<<4 - a;
result = {a,4'b0} - a; // unsigned full-subtractor
result = {a,4'b0} + ~a + 1'b1; // unsigned full-adder w/ carry in, 2's complement
result = {{3{a[3]}},a,4'b0} + ~{ {7{a[3]}}, a} + 1'b1; // signed full-adder w/ carry in, 2's complement
The cleanest RTL version is as you have stated in the question:
module mul15(
input [3:0] a
output reg [7:0] result,
);
always #* begin
result = a * 4'd15;
end
endmodule
The Multiplicand 15 in binary is 4'b1111; That is 8 + 4 + 2 + 1.
Instead of a multiplier it could be broken down into the sum of these powers of 2. Powers of 2 are just barrel shifts. This is how a shift and add multiplier would work.
module mul15(
input [3:0] a
output reg [7:0] result,
);
always #* begin
// 8 4 2 1 =>15
result = (a<<3) + (a<<2) + (a<<1) + a;
end
endmodule
To minimise the number of adders required a CSD could be used. making 15 out of 16-1:
module mul15(
input [3:0] a
output reg [7:0] result,
);
always #* begin
// 16 - 1 =>15
result = (a<<4) - a;
end
endmodule
With a modern synthesis tool these should all result in same the thing. Therefore having more readable code which gives a clear instruction to the tool as to what you intended gives it the free rein to optimise as required.

number of ones in array

I am trying to count the number of ones in a 4-bit binary number in Verilog, but my output is unexpected. I've tried several approaches; this is the one I think should work, but it doesn't.
module ones(one,in);
input [3:0]in;
output [1:0]one;
assign one = 2'b00;
assign one = one+in[3]+in[2]+in[1]+in[0] ;
endmodule
First, you can't assign the variable twice.
Second, your range is off, 2 bits can only go from 0 to 3. You need a 3 bit output to count up to 4.
This is more like what you need:
module ones(
output wire [2:0] one,
input wire [3:0] in
);
assign one = in[3]+in[2]+in[1]+in[0] ;
endmodule
$countones can be used for this purpose (refer to IEEE Std 1800-2012, 20.9 Bit vector system functions):
module tb;
reg [3:0] in;
wire [2:0] one = $countones(in);
initial begin
$monitor("in=%b one=%d", in, one);
#1 in = 4'b0000;
#1 in = 4'b0001;
#1 in = 4'b1101;
end
endmodule
Output:
in=xxxx one=0
in=0000 one=0
in=0001 one=1
in=1101 one=3

Resources