Shifting a Concatenate Register - verilog

Ive been doing verilog HDL in quartus II for 2 month now and have not synthesized any of my codes yet. I am struggling to code a fractional division circuit. Of course theres a lot of problems...
I would like to know how do I concatenate two registers to form a larger register that I can shift to the right where the shifting of the data would occur at every positive edge of the clock pulse... The data in the newly created register has 3 zeros (MSB) followed by 4 data bits from another register called divider.
For example B=[0 0 0]:[1 0 1 0]
I have tried the following
module FRACDIV (divider,clk,B,START,CLR);
input [3:0] divider;
input START, CLR, clk;
output [6:0] B;
reg [6:0] B;
always # (posedge clk)
begin
B = {3'd0, divider};
if (START == 1'b1)
begin
B=B+B<<1;
end
end
endmodule
Any help would be deeply appreciated as I've been trying to figure this out for 5 hours now...
Mr. Morgan,
Thank you for the tips. The non-blocking statement did help. However the code would not shift perhaps because B is always reinitialized at every clock pulse as it is outside the if statement.
With a fresh new day and a fresh mind and owing to your suggestion using the non-blocking statement I tried this...
module FRACDIV(divider,clk,B,START,CLR);
input [3:0] divider;
input START, CLR, clk;
output [6:0] B;
reg [6:0] B;
always # (posedge clk)
begin
if (START) begin
B <= {3'b0, divider};
end
else begin
B <= B <<1;
end
end
endmodule
The if statement loads data into B whenever START is HIGH. When START is LOW, the data shifts at every positive edge of the clock. Is there anyway to make the data in B to start shifting right after loading it with the concatenated data without the if statement?
Just curious and I still do not feel this code is the most efficient.

When implying flip-flops it is recommended to use <= non-blocking assignments.
When declaring outputs you should also be able to delcare it as a reg, unless you are stuck using a strict verilog-95 syntax.
module FRACDIV (
input [3:0] divider,
input START, CLR, clk,
output reg [6:0] B
);
always # (posedge clk) begin
B <= {3'd0, divider};
if (START == 1'b1) begin
B<=B+B<<1; //This will overide the previous statement when using `<=`
end
end
endmodule
This will simulate in the same way that your synthesised code will perform on the FPGA.

Related

How to assign initial value to an input reg: Design compiler delete the assignment

I'm newbie in ASIC design. I have a design with for example two inputs a ,b. I'm using the following code for initialize these two signals. But the Design compiler generating a warning that the register "a" is a constant and will be removed. When I'm trying to do post-synthesis simulation these two signals are all 'z'. So how can I apply initial signal assignment to avoid such a problem?
always #(posedge(clk) or posedge (rst)) begin
if (rst) begin
a<=4d'5;
b <=4'd10;
end
end
While describing hardware system, you need to consider that input signals to your module comes from another module/system and their values are decided by that signals. Inputs to any module can only be wire type.
You can think of a module as a box that has inputs and outputs. The values of output signals are decided by input signal + logic inside the box. However, the module cannot decide what its inputs should be. It is only possible if there is feedback, and even in that case it would depend on other signals that are outside of the module's control.
As a result, output signals can be declared as output reg but the same is not true for inputs. However there is solution to your problem, I think what you want can be designed using the following method:
module your_module(
input clk,
input rst,
//other inputs and outputs that you might need
input [3:0] a,
input [3:0] b
);
//define registers
reg [3:0] a_register;
reg [3:0] b_register;
/*
These registers are defined to make it possible to
to give any value to that logics when posedge rst
is detected, otherwise you can use them as your
input logics
*/
//use initial block if you need
always#(posedge clk or posedge rst) begin
if(rst) begin
a_register <= 4'd5;
b_register <= 4'd10;
end
else
begin
a_register <= a;
b_register <= b;
// and use a_register and b_register as you want to use a and b
end
end
endmodule

Verilog - re-using register value on always posedge

Consider the following code:
Module Test (B, A, CLK)
Input A, CLK;
Output B;
Reg RA;
Always #(Posedge CLK)
Begin
RA=A;
B=RA;
End
EndModule
Would that work properly to move the input to the register and then to the output on every positive edge? Can it be created with circuits?
It depends what you are trying to do...
If you just want a single flip-flop, the simplest way is to declare reg B; then you can write always #(posedge CLK) B <= A;. There is no need for another signal.
If (for some style reason) you want to separate the flip-flop from the output, you can wire them together with a continuous assignment assign B = RA;. The circuit would be the same.
If you want two flip-flops (2-stage pipeline), your code is almost correct but remember to declare reg B; and use <= for both updates (they can be written in either order).
If RA is some sort of temporary variable for describing your intentions to the tools, then Yes; you can write to it with = and use its value in the same process (do not try to access it from any other process). This is occasionally useful for e.g. accumulating things in loops, but here it would just be confusing and error-prone!
To synthesize real hardware you would typically also have a reset signal and would need to use it in the proper way for each flip-flop.
To answer your question, yes, what you've written (conceptually) will work. In terms of syntax, here's something that will compile and do what you're thinking. Note that I've declared your output B a register and used nonblocking assignments for the registers.
module Test (
input wire CLK,
input wire A,
output reg B
);
reg RA;
always #(posedge CLK) begin
RA <= A;
B <= RA;
end
endmodule

Modelsim - Object not logged & no signal data while simulating verilog clock divider code

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

two clock ring counter with verilog

I'm trying to write a roll shift/ ring counter that takes two switches as the clocks in verilog.
My code is as follows:
module roll(CLK1, CLK2, LEDS);
input CLK1;
input CLK2;
output [3:0] LEDS;
reg [3:0] LEDS;
initial
begin
LEDS = 4'b0001;
end
always#(posedge CLK1 or posedge CLK2)
begin
if(CLK1)
begin
LEDS[3]<=LEDS[2];
LEDS[2]<=LEDS[1];
LEDS[1]<=LEDS[0];
LEDS[0]<=LEDS[3];
end
// Roll Right
if(CLK2)
begin
LEDS[3]<=LEDS[0];
LEDS[2]<=LEDS[3];
LEDS[1]<=LEDS[2];
LEDS[0]<=LEDS[1];
end
end
endmodule
I tried using two always blocks, but then figured out that I cannot do that. and when I have the posedge CLK2 in the always statement, the leds on my FPGA all stay on.
Remember Verilog is not a programming language it is a hardware description language.
And when coding for synthesis, you will only be successful if you write code that can be instantiated with actual gates. So writing an always block with sensitivity to edges of two different signals can't be synthesized unless the response to one of the two signals has the effect of a RESET or PRESET operation.
Your code also logically doesn't do what it seems you want to. Consider what your code says will happen if there is a rising edge on CLK2 when CLK1 is already high (or vice versa). Your lights will roll left and then immediately roll right gain, resulting in no change.
A more usual approach would be to have a clock running much faster than the UP and DOWN inputs are expected to change, and use that to drive the logic. For example
module roller(input clk, input rst, input UP, input DOWN, output reg LEDS[3:0]);
reg UP1, DOWN1;
always #(posedge clk or posedge rst)
if (rst) begin
LEDS[3:0] <= 4'b0001;
end
else
begin
UP1 <= UP;
DOWN1 <= DOWN;
if (UP & ~UP1) begin
LEDS[3:0] <= {LEDS[2:0], LEDS[3]};
end
else if (DOWN & ~DOWN1) begin
LEDS[3:0] <= {LEDS[0], LEDS[3:1]};
end
end
endmodule;
Notice that this gives priority to UP. If both UP and DOWN are asserted, the pattern will roll "up" rather than down. If you want a different behavior, you'd have to modify the code to achieve it.

Connecting a 4 bit shift register output to a 4 bit input in another module in Verilog

For our school project I am trying to use linear feedback shift register for pseudo-random number generation on hardware (seven segment). I have written the LFSR and seven segment module, however I have trouble connecting the two modules with each other. The project synthesizes but the HDL Diagram does not show any connection between LFSR and seven segment module. Below is the code.
//main module
module expo(input clock, reset,
output a,b,c,d,e,f,g
);
wire [3:0]connect, clk, a,b,c,d,e,f,g;
LFSR_4_bit lfsr(
.clock(clock),
.LFSR(connect)
);
seven_seg seven(
.in(connect),
.reset(reset),
.a(a),
.b(b),
.c(c),
.d(d),
.e(e),
.f(f),
.g(g)
);
endmodule
//LFSR module
module LFSR_4_bit(
input clock,
output reg[3:0]LFSR = 15
);
wire feedback = LFSR[4];
always #(posedge clock)
begin
LFSR[0] <= feedback;
LFSR[1] <= LFSR[0];
LFSR[2] <= LFSR[1];
LFSR[3] <= LFSR[2] ^ feedback;
LFSR[4] <= LFSR[3];
end
endmodule
//input and output for seven seg module
module sevenseg(
input reset,
input[3:0] in, //the 4 inputs for each display
output a, b, c, d, e, f, g, //the individual LED output for the seven segment along with the digital point
output [3:0] an // the 4 bit enable signal
);
Thanks for the help.
1) You instantiate seven_seg but the module is called module sevenseg This is a compile error.
2) Your LFSR has 4 bits 0 to 3, a fifth bit LFSR[4] is used, this is also a compile error.
Due to the compile errors I am not sure that your viewing the results of the current synthesis, as it should have failed. It is quite likely that you are viewing an old result before they were connected.
Other things I would change:
a) When you define wire [3:0]connect, clk, a,b,c,d,e,f,g; they are all 4 bits.
However as clock (not clk) and a,b,c,d,e,f,g are defined in your port list they are already declared. That line could just be wire [3:0]connect.
b) When initialising values for flip-flop and not using a reset it is better practise to use an initial begin : This is valid for FPGA's not for ASICs where you should use reset signals
initial begin
LFSR = 4'd15;
end

Resources