I'm an FPGA noob trying to learn Verilog. How can I "assign" a value to a reg in an always block, either as an initial value, or as a constant. I'm trying to do something like this in the code below. I get an error because the 8 bit constant doesn't count as input. I also don't want to trigger the always off of a clock. I just want to assign a register to a specific value. As I want it to be synthesisable I can't use an initial block. Thanks a lot.
module top
(
input wire clk,
output wire [7:0] led
);
reg [7:0] data_reg ;
always #*
begin
data_reg = 8'b10101011;
end
assign led = data_reg;
endmodule
You can combine the register declaration with initialization.
reg [7:0] data_reg = 8'b10101011;
Or you can use an initial block
reg [7:0] data_reg;
initial data_reg = 8'b10101011;
You should use what your FPGA documentation recommends. There is no portable way to initialize register values other than using a reset net. This has a hardware cost associated with it on most synthesis targets.
The other answers are all good. For Xilinx FPGA designs, it is best not to use global reset lines, and use initial blocks for reset conditions for most logic. Here is the white paper from Ken Chapman (Xilinx FPGA guru)
http://japan.xilinx.com/support/documentation/white_papers/wp272.pdf
The always #* would never trigger as no Right hand arguments change. Why not use a wire with assign?
module top (
input wire clk,
output wire [7:0] led
);
wire [7:0] data_reg ;
assign data_reg = 8'b10101011;
assign led = data_reg;
endmodule
If you actually want a flop where you can change the value, the default would be in the reset clause.
module top
(
input clk,
input rst_n,
input [7:0] data,
output [7:0] led
);
reg [7:0] data_reg ;
always #(posedge clk or negedge rst_n) begin
if (!rst_n)
data_reg <= 8'b10101011;
else
data_reg <= data ;
end
assign led = data_reg;
endmodule
Hope this helps
When a chip gets power all of it's registers contain random values. It's not possible to have an an initial value. It will always be random.
This is why we have reset signals, to reset registers to a known value. The reset is controlled by something off chip, and we write our code to use it.
always #(posedge clk) begin
if (reset == 1) begin // For an active high reset
data_reg = 8'b10101011;
end else begin
data_reg = next_data_reg;
end
end
Related
This question already has answers here:
Why is this code getting inferred latches?
(2 answers)
Closed 5 months ago.
I am design a register file module and I am trying to prevent the "inferred latch warning". The module allows for asynchronous reads but synchronous writes. This is what I have designed so far. I generally know what latches are, but can't think of a solution to prevent latches in this case. What would I define as the else statement so that the regfile doesn't create inferred latches?
module register_file (
input wire clk,
input wire rst,
input wire [4:0] raddr_a,
input wire [4:0] raddr_b,
output reg [15:0] rdata_a,
output reg [15:0] rdata_b,
input wire [4:0] waddr,
input wire [15:0] wdata,
input wire we
);
reg [15:0] regfile [0:31];
/// 32 x 16 bit register file
// asynchronous reads
// don't allow read zero register
assign rdata_a = (raddr_a == 5'd0) ? 16'd0 : regfile[raddr_a];
assign rdata_b = (raddr_b == 5'd0) ? 16'd0 : regfile[raddr_b];
integer i;
always #(clk) begin
// reset registers
if (rst) begin
for (i = 0; i < 32; i = i + 1) begin
regfile[i] <= 0;
end
end else begin
// if write enabled, write to register at waddr
if (we == 1'b1) begin
regfile[waddr] <= wdata;
end
end
end
endmodule
Would I set the value to itself? How would I go on preventing an inferring latch? Thanks!
Change always statement from:
always #(clk) begin
to:
always #(posedge clk) begin
I was able to run the posted code on EDA Playground Yosys; it produces latches.
After the change, latches are no longer produced.
Pretty simple problem. Given the following code:
module main(
output reg [1:0][DATA_WIDTH-1:0] dOut,
input wire [1:0][DATA_WIDTH-1:0] dIn,
input wire [1:0][ADDR_WIDTH-1:0] addr,
input wire [1:0] wren,
input wire clk
);
parameter DATA_WIDTH = 16;
parameter ADDR_WIDTH = 6;
reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
generate
genvar k;
for(k=0; k<2; k=k+1) begin: m
always #(posedge clk) begin
if(wren[k])
ram[addr[k]] <= dIn[k];
dOut[k] <= ram[addr[k]];
end
end
endgenerate
endmodule
quarus 13.0sp1 gives this error (and its 20 other ill-begotten fraternally equivalent siblings):
Error (10028): Can't resolve multiple constant drivers for net "ram[63][14]" at main.v(42)
But if I manually un-roll the generate loop:
module main(
output reg [1:0][DATA_WIDTH-1:0] dOut,
input wire [1:0][DATA_WIDTH-1:0] dIn,
input wire [1:0][ADDR_WIDTH-1:0] addr,
input wire [1:0] wren,
input wire clk
);
parameter DATA_WIDTH = 16;
parameter ADDR_WIDTH = 6;
reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
always #(posedge clk) begin
if(wren[0])
ram[addr[0]] <= dIn[0];
dOut[0] <= ram[addr[0]];
end
always #(posedge clk) begin
if(wren[1])
ram[addr[1]] <= dIn[1];
dOut[1] <= ram[addr[1]];
end
endmodule
It all becomes okay with the analysis & synthesis step.
What's the cure to get the generate loop running?
I think the correct way is in the lines of what it's explained in this question: Using a generate with for loop in verilog
Which would be transferred to your code as this:
module main(
output reg [1:0][DATA_WIDTH-1:0] dOut,
input wire [1:0][DATA_WIDTH-1:0] dIn,
input wire [1:0][ADDR_WIDTH-1:0] addr,
input wire [1:0] wren,
input wire clk
);
parameter DATA_WIDTH = 16;
parameter ADDR_WIDTH = 6;
reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
integer k;
always #(posedge clk) begin
for(k=0; k<2; k=k+1) begin:
if(wren[k])
ram[addr[k]] <= dIn[k];
dOut[k] <= ram[addr[k]];
end
end
endmodule
Keeping all accesses to your dual port RAM in one always block is convenient so the synthesizer can safely detect that you are efefctively using a dual port RAM at register ram.
Both the generate loop and unrolled versions should not have passed synthesis. In both cases the same address in ram can be assigned by both always blocks. Worse, if both bits of wren are high with both addresses being the same and data being different, then the result is indeterminable. The Verilog LRM states last assignment on a register wins and always blocks with the same trigger could be evaluated in any order.
Synthesis requires assignments to registers to be deterministic. Two (or more) always blocks having write access to the same bit is illegal because nondeterministic. If the unrolled is synthesizing correctly, then that means there are constants on wren and addr outside of the shown module that make it logically impossible for write conflict; for some reason the generate loop version is not getting the same optimization. Example of constraints that would allow optimization to prevent multi-always block write access:
One wren is hard coded to 0. Therefore only one block has exclusive access
Address have non overlapping sets of possible values. Ex addr[0] can only be even while addr[1] can only be odd, or addr[0] < 2**(ADDR_WIDTH/2) and addr[1] >= 2**(ADDR_WIDTH/2).
Synthesis is okay with dOut being assigned by two always blocks because each block has exclusive write access to its target bits (non overlapping sets of possible address values).
The single always block in mcleod_ideafix answer is the preferred solution. If both bits of wren are high with both addresses being the same, then wren[1] will always win. If wren[0] should have priority, then make the for-loop a count down.
What I'm trying to do: I wish to count numbers from 0 to hexadecimal F and display these on my FPGA board at different frequencies - my board's clock (CLOCK_50) is at 50 MHz and I wish to alter the frequency/speed of the counting based on two input switches on my board (SW[1:0]).
Verilog Code for top-module & clock divider module:
//top level module
module rate_divider (input CLOCK_50, input [1:0] SW, input [1:0] KEY,output [6:0] HEX0);
//Declare parameters that define the # of clock cycles needed to generate an enable pulse
according to the desired frequency.
parameter FREQ_5MHz = 4'd9; //To divide to 5 MHz we need (10-1) cycles,
//since the pulse needs to start at the 9th cycle.
parameter FULL50_MHz = (4'd1); //The CLOCK_50's Frequency.
//Select the desired parameter based on the input switches
reg [3:0] cycles_countdown;
wire enable_display_count;
wire [3:0] selected_freq;
always #(*)
case (SW)
2'b00: cycles_countdown = FULL50_MHz;
2'b01: cycles_countdown = FREQ_5MHz;
default : cycles_countdown = FULL50_MHz;
endcase
assign selected_freq = cycles_countdown;
//wire that is the output of the display_counter and input to the 7 segment
wire [3:0] hex_value;
// instantiate my other modules
clock_divider_enable freq_divider (.d(selected_freq), .clk(CLOCK_50), .reset(KEY[0]),
.enable(enable_display_count));
display_counter count_hex (.enable(enable_display_count), .clk(CLOCK_50), .hex_out(hex_value), .reset(KEY[1]));
hex_decoder HX0 (.hex_digit(hex_value), .segments(HEX0[6:0]));
endmodule
//the clock_divider sub-circuit.
module clock_divider_enable (input [3:0] d, input clk, reset,
output enable);
reg [3:0] q;
always #(posedge clk)
begin
if (!reset || !q)
q <= d;
else
q <= q - 4'd1;
end
assign enable = (q == 4'h0) ? 1'b1 : 1'b0;
endmodule
ModelSim Code:
vlib work
vlog rate_divider.v
vsim rate_divider
log {/*}
add wave {/*}
#initial reset - using KEY[1:0]. Note: active low synchronous reset.
force {CLOCK_50} 1
force {KEY[0]} 0
force {KEY[1]} 0
run 10ns
#choose 5 MHz as the desired frequency - turn SW[0] high.
force {CLOCK_50} 0 0ns, 1 {10ns} -r 20ns
force {KEY[0]} 1
force {KEY[1]} 1
force {SW[0]} 1
force {SW[1]} 0
run 600ns
Problems I am facing:
Here's the thing - when I don't use the always block to select a parameter, and pass a desired parameter to the wire selected_freq, my simulation works fine - I can see the expected enable pulse.
HOWEVER, if I use the always block, the reg cycles_countdown does get the correct value assigned, BUT for some reason the enable signal is just a red line. When I select my clock_divider_enable module and add it's 'q' signal onto my waveform, it is red too and shows no data, and the object q is "not logged". As such, I'm unable to debug and figure out what exactly the problem with my code is.
It'd be great if someone could help with how to fix the simulation issue rather than just point out the issue with my Verilog code since I want to learn how to use ModelSim efficiently so that in the future debugging will be easier for me.
Equipment Used:
FPGA: Altera De-1-SoC, Cyclone V chip
CAD/Simulation Tools: Altera Quartus II Lite 17.0 + ModelSim Starter Edition
SW wasn't given an initial value, therefore it is high-Z (X if connected to a reg).
I'm guessing when you used the parameter approach you were parameterizing cycles_countdown. Some simulators do not trigger #* at time-0. So if there isn't a change on the senctivity list, then the block may not execute; leaving cycles_countdown as its initial value (4'hX).
Instead of driving your test with TCL commands, you can use create a testbench in with verilog. This testbench should only be used in simulation, not synthesis.
module rate_devider_tb;
reg CLOCK_50;
reg [1:0] SW;
reg [1:0] KEY;
wire [6:0] HEX0;
rate_divider dut( .CLOCK_50(CLOCK_50), .SW(SW), .KEY(KEY), .HEX0(HEX0));
always begin
CLOCK_50 = 1'b1;
#10;
CLOCK_50 = 1'b0;
#10;
end
initial begin
// init input signals
SW <= 2'b01;
KEY <= 2'b00;
// Log file reporting
$monitor("SW:%b KEY:%b HEX0:%h # %t", SW, KEY, HEX0, $time);
// waveform dumping
$dumpfile("test.vcd");
$dumpvars(0, rate_devider_tb);
wait(CLOCK_50 === 1'b0); // initialization x->1 will trigger an posedge
#(posedge CLOCK_50);
KEY <= 2'b01; // remove reset after SW was sampled
#600; // 600ns assuming timescale is in 1ns steps
$finish();
end
I am implementing a 32bit RegFile(containing 32 registers). Now, for the combinational part, I am planning to use the switch case to out the read value of the 32registers based on the input register number. This is resulting in a switch case with 32cases and a default case. Is there any other way to optimize the code? Constraint is that my output needs to be a register and hence I am unable to use the following statement(containing assign):
assign rdDataA = rdAddrA == 0 ? reg0
Code:
module RegFile(input [4:0] src_rd_1,
input [4:0] src_rd_2,
input [4:0] des_wr_1,
input [31:0] data,
input clk,
input reset,
input wr_en,
output reg rd_val_1,
output reg rd_val_2
);
reg [31:0] register[31:0];
always_comb begin
case(src_rd_1)
5'd0:begin
rd_val_1=register[0];
end
5'd1:begin
rd_val_1=register[1];
end
5'd2:begin
rd_val_1=register[2];
end
5'd3:begin
rd_val_1=register[3];
end
5'd4:begin
rd_val_1=register[4];
//and so on...
end
Update:
I found out a way to optimize the code. I hope this would work...Any other suggestions are welcome
if(src_rd_1>=0)
begin
if(src_rd_1==0)
begin
rd_val_1=32'd0;
end
else
begin
rd_val_1=register[src_rd_1];
end
end
Any advise will helpful. TIA
The following is allowed by simulation tools:
always_comb begin
rd_val_1 = register[src_rd_1];
end
You'll have to try it out and see if your synthesis tool supports this.
Using reg doesn't mean it will synthesize to a register. To synthesize to a register a reg (or for SystemVerilogpreferablylogic`) should be assigned in a sequential always block.
always_ff #(posedge clk) begin
rd_val_1 <= register[src_rd_1];
end
Flopping the output makes it a clean, glitch-free output and doesn't add to the combinational propagation delay to any receiving modules.
I'm new to Verilog and I'm trying to create a 4-bit binary Random Number Generator. The program is as follows, could anyone help me by mentioning the errors?
I initially tried out this:
module rng (d);
inout[3:0]d;
//wire[3:0]d;
//input clk, rst;
//wire [3:0] w;
dff f1(a[0],clk,d[0],rst);
dff f2(a[1],clk,d[1],rst);
dff f3(a[2],clk,d[2],rst);
dff f4(a[3],clk,d[3],rst);
xorper p(d[0],d[1],d[2],d[3],a[0],a[1],a[2],a[3]);//permutations
//dff f1(a,clk,q,rst);
dff x(d,clk,q,rst);
endmodule
I also tried out this:
module re(b,q,clk,rst);
input [3:0]q;
input clk,rst;
wire [3:0]q,a;
output [3:0]b;
reg [3:0]b;
rox f1(q[0],q[1],q[2],q[3],a[0],a[1],a[2],a[3]);//permutations
rod f2(a,clk,b,rst);//dff
always#(posedge clk) begin
if (rst==1'b0) begin
b[0]=q[0];
b[1]=q[1];
b[2]=q[2];
b[3]=q[3];
end else if(rst==1'b1)
b[0]=1'bx;
b[1]=1'bx;
b[2]=1'bx;
b[3]=1'bx;
end
endmodule
I would suggest starting with an LFSR for random number generation. They are a straight forward shift register, with taps back to a mutlibit XOR to create the feedback bit.
Your implementation of a flop could be better.
1) Add negedge rst to the sensitivity list
2) You do not want to assign x's
3) use non-blocking assignments (<=)
reg [3:0] b;
//LFSR feedback bit
wire feedback
assign feedback = b[0] ^ b[3];
// Add active low reset to sensitivity list
always#(posedge clk or negedge rst) begin
if (rst==1'b0) begin
b[3:0]<=4'hF; //reset condition first
end
else begin
b[0]<=feedback;
b[1]<=b[0];
b[2]<=b[1];
b[3]<=b[2];
//Alternative Verilog might be
// b = {b[2:0], feedback};
end
For choosing tap point for an LFSR search for a maximal length LFSR. A maximal LFSR will have the longest number sequence before it repeats for a given length of register and tap points.