How can you output a constant value in Verilog? - verilog

I am trying to output an array of 1280 bits, each 10 bits long, with the numbers 0->128.
I heard localparam may be the best option, but it seems like a strange request, so I'm wondering if anyone with experience may be able to help me.
Thanks

You can create a function that provides a constant value to a localparam or any other signal.
wire [1279:0] signal;
assign signal = pattern(0);
function [1279:0] pattern(input arg); // Verilog requires at least one argument to a function
integer i;
begin
for (i=0;i<128;i=i+1)
pattern[i*10 +:10] = i;
end
endfunction
SystemVerilog:
wire [1279:0] signal;
assign signal = pattern();
function bit [1279:0] pattern();
for (int i=0;i<128;i++)
pattern[i*10 +:10] = i;
endfunction

You can use a for-loop in an initial or reset statement:
reg [0:1279] big_vector;
integer i;
// here you need an initial
// or a reset section
for (i=0; i<128; i=i+1)
big_vector[ i*128 +: 10] = i;
If you do not touch/change big_vector the synthesis tool will convert it to a constant.

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.

Will temp variable in always_comb create latch

I have following code snippet where a temp variable is used to count number of 1s in an array:
// count the number 1s in array
logic [5:0] count_v; //temp
always_comb begin
count_v = arr[0];
if (valid) begin
for (int i=1; i<=31; i++) begin
count_v = arr[i] + count_v;
end
end
final_count = count_v;
end
Will this logic create a latch for count_v ? Is synthesis tool smart enough to properly synthesize this logic? I am struggling to find any coding recommendation for these kind of scenarios.
Another example:
logic temp; // temp variable
always_comb begin
temp = 0;
for (int i=0; i<32; i++) begin
if (i>=start) begin
out_data[temp*8 +: 8] = in_data[i*8 +: 8];
temp = temp + 1'b1;
end
end
end
For any always block with deterministic initial assignment, it will not generate latch except logic loop.
Sorry Eddy Yau, we seem to have some discussions going on regarding your post.
Here is some example code:
module latch_or_not (
input cond,
input [3:0] v_in,
output reg latch,
output reg [2:0] comb1,
output reg [2:0] comb2
);
reg [2:0] temp;
reg [2:0] comb_loop;
// Make a latch
always #( * )
if (cond)
latch = v_in[0];
always #( * )
begin : aw1
integer i;
for (i=0; i<4; i=i+1)
comb_loop = comb_loop + v_in[i];
comb2 = comb_loop;
end
always #( * )
begin : aw2
integer i;
temp = 7;
for (i=0; i<4; i=i+1)
temp = temp - v_in[i];
comb1 = temp;
end
endmodule
This is what came out if it according to the Xilinx Vivado tool after elaboration:
The 'latch' output is obvious. You will also notice that temp is not present in the end result.
The 'comb_loop' is not a latch but even worse: it is a combinatorial loop. The output of the logic goes back to the input. A definitely NO-NO!
General rule: if you read a variable before writing to it, then your code implies memory of some sort. In this case, both the simulator and synthesiser have to implement storage of a previous value, so a synthesiser will give you a register or latch. Both your examples write to the temporary before reading it, so no storage is implied.
Does it synthesisie? Try it and see. I've seen lots of this sort of thing in production code, and it works (with the synths I've used), but I don't do it myself. I would try it, see what logic is created, and use that to decide whether you need to think more about it. Counting set bits is easy without a loop, but the count loop will almost certainly work with your synth. The second example may be more problematical.

Verilog : Variable index is not supported in signal

I get an error saying 'Index is not supported in signal'. From what I can see the error is on the left hand side of the non-blocking assignment. Why does the code below give an error and is there a way to work around it?
...
parameter width = 32;
parameter size = 3;
input clk, reset;
input [width*size-1:0] A;
input [width*size-1:0] B;
output [width*size-1:0] result;
reg signed [width*size-1:0] partials;
reg signed [width-1:0] temp;
reg signed [width-1:0] currenta;
reg signed [width-1:0] currentb;
wire signed [width-1:0] temp1wire;
...
integer k = 0;
always # (posedge clk)
begin
currenta[width-1:0] <= A[width*k +: width];
k = k+1
currentb[width-1:0] <= B[width*k +: width];
partials[width*k +: width] <= temp1wire;
end
Add Add1(clk, temp1wire, currenta, currentb);
...
This code is part of a sequential block that does vector addition and saves the result at partials[width*k +: width].
I found this on the Xilinx forum:
"XST works fine with the indexed part-select operator "+:" if it is on the right-hand side (RHS) of the assignment. It also works fine when it is on the left-hand side (LHS) AND the starting index is a constant. Your case uses a variable as the starting index on the LHS and that what XST doesn't like although it's legal."
k needs to be clamped or wrapped around after reaching size-1.
Wrapping around can be done with the mod operator (%); example:k = (k+1)%size. % may not synthesize optimally (check your synthesizer), so a if-statement is a functional alternative if(k==SIZE-1) k = 0; else k=k+1;
Suggestions:
It is generally recommenced to keep parameters as uppercase, this way you can easily identity parameters form signal names. Putting a blocking assignment inside a sequential block is legal, but most design rules recommend separating combinational logic from sequential assignments. I would prefer writing your code like the following:
// $clog is IEEE1364-2005 § 17.11, some synthesizers support it, others don't
reg [$clog2(SIZE):0] k=0, next_k;
always #* begin
if (k==SIZE-1) begin
next_k = 0; // wrap around
// next_k = k; // clamp
end
else begin
next_k = k+1;
end
end
always # (posedge clk)
begin
currenta[WIDTH-1:0] <= A[WIDTH*k +: WIDTH];
currentb[WIDTH-1:0] <= A[WIDTH*next_k +: WIDTH];
partials[WIDTH*next_k +: WIDTH] <= temp1wire;
k <= next_k;
end

How to constrain a counter reg size in verilog for ise synthesis?

I want to declare a counter reg in function of some parameters. I did it in this way :
parameter clk_freq = 95000; // clock frequency in kHz
parameter debounce_per_ms = 20;
localparam MAX_COUNT = ((debounce_per_ms * clk_freq)) + 1;
reg [$ln(MAX_COUNT)/$ln(2):0] count;
This work well in simulation with icarus but ISE 14.7 don't want to synthesize it. That give this error:
WARNING:HDLCompiler:1499 - "/src/button_deb.v" Line 4: Empty module <button_deb> remains a black box.
If I define the count like this :
reg [22:0] count;
ISE synthesize it well. If someone have a clue ?
This worked for me, although I'd swear I used functions like $log, $log10, $ceil and the like in the past with no problems.
module param_with_log2 (
input wire clk,
output wire d
);
function integer log2;
input integer value;
begin
value = value-1;
for (log2=0; value>0; log2=log2+1)
value = value>>1;
end
endfunction
parameter clk_freq = 95000; // clock frequency in kHz
parameter debounce_per_ms = 20;
localparam MAX_COUNT = ((debounce_per_ms * clk_freq)) + 1;
localparam integer UPPER = log2(MAX_COUNT);
reg [UPPER:0] count;
always #(posedge clk)
count <= count + 1;
assign d = count[UPPER];
endmodule
XST seems to have a problem with using constant functions: they only can be at the right side of a parameter declaration expression (as I suggested in my first comment). Credits and more information here:
http://www.beyond-circuits.com/wordpress/2008/11/constant-functions/
Notice too that UPPER is declared as localparam integer so we can use it inside a register definition upper bound expression. Credits go to the owner of this post: http://forums.xilinx.com/t5/Synthesis/XST-and-clog2/m-p/244440/highlight/true#M6609
(the module is just a phony module to have something that I can symthesize without the fear that the synthesizer will wipe all my code. It doesn't perform any kind of debouncing)

How to dynamically reverse the bit position in verilog?

wire [9:0] data_reg;
reg [3:0] Reverse_Count = 8; //This register is derived in logic and I need to use it in following logic in order to reverse the bit position.
assign data_reg[9:0] = 10'h88; // Data Register
genvar i;
for (i=0; i< Reverse_Count; i=i+1)
assign IReg_swiz[i] = IReg[Reverse_Count - 1 -i];
This is generating syntax error. May I know how to do this in verilog
If you'd have Reverse_Count as constant, your task boils down to just wire mix-up, which is essentially free in HDL.
In your case, the task can be nicely reduced to first mirroring wide data and then shifting by Reverse_Count to get LBS bit on its position, which itself is done just by a row of N-to-1 multiplexers.
integer i;
reg [9:0] reversed;
wire [9:0] result;
// mirror bits in wide 10-bit value
always #*
for(i=0;i<10;i=i+1)
reversed[i] = data_reg[9-i];
// settle LSB on its place
assign result = reversed>>(10-Reverse_Count);
Reverse_Count is not a constant, ie it is not a parameter or localparam.
This means that the generate statement you would be creating and destroying hardware as required, this is not allowed in verilog as it would not be possible in hardware.
The Bus that your reversing should have a fixed width at compile time, it should be possible to declare Reverse_Count as a parameter.
Since the value of Reverse_Count dunamic, you cannot use a generate statement. You can use an always block with for-loop. To be synthesizable, the for-loop needs able to static unroll. To decide which bits reverse, use an if condition to compare the indexing value and Reverse_Count
Example:
parameter MAX = 10;
reg [MAX-1:0] IReg_swiz;
integer i;
always #* begin
for (i=0; i < MAX ; i=i+1) begin
if (i < Reverse_Count) begin
IReg_swiz[i] = IReg[Reverse_Count - 1 -i];
end
else begin
// All bits need to be assigned or complex latching logic will be inferred.
IReg_swiz[i] = IReg[i]; // Other values okay depending on your requirements.
end
end
end

Resources