Shift Register in verilog - verilog

I have designed a serial in parallel out shift register as input register for an encoder
module ShiftRegister_SIPO(clk, in, out);
input clk,in;
output [3:0] out;
reg [3:0] tmp;
always #(posedge clk)
begin
tmp = {tmp[2:0], in};
end
assign PO = tmp;
endmodule
how do I retain the value once the desired parallel out data is got , even with clk=1? Because even after the output data is got the value keeps shifting. For example ,if i give
Part of testbench
in=1;
#10
in=0;
#10
in=1;
#10
in=1;
#5 clk=~clk;
I get 1011 at the 4th clock cycle , but the value then keeps shifting. Can i retain it as 1011 for the remaining period also, still keeping the clk=1.
Thanks in advance

In you example the value will be shifting every positive edge of the clock. In order to prevent it from shifting under some circumstances you need a way to enable or disable shifting. For example:
always #(posedge clk)
begin
if (enable)
tmp <= {tmp[2:0], in};
end
So, controlling the enable signal you can control shifting. If its value is low, then no shifting will happen and the value of 'tmp' will remain unchanged till you enable it again.

Related

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.

Verilog always#(..) output not working as expected

So, im trying to synthesize my verilog code to send data from ps2 keybord ->fpga->vga. Just for the background of the code, I want to press the button "1", and that to appear on the center of the screen (called the display_area)
I realised that something is not working as expected.
After carefull debugging, i realised that the problem lies in the module that converts the parallel data bus from the rom, into serial output, to assign a value in each pixel.
The code itself is pretty simple, im just providing as much info as i can.
We need a positive edge of the clock to enter the always area (or a reset). If the value display_area_enable is 1, we activate a counter from 7 till 0 (8 cycles) to index the data from the rom.
However, on the first clock, if the display area becomes 1 the exact moment when the vga_clk pulse becomes 1, the counter gets the value as it should, but the one_bit_output (the output of the module) doesnt. One_bit_output gets its first correct value the 2nd time that the always block is accessed. as a result we need 9 cycles to access an 8 bit bus.
I ll provide the code and a modelsim testbench
module shifter(reset,char_rom_data_out,vga_clk,display_area_enable,one_bit_output,counter);
input [7:0]char_rom_data_out;
input vga_clk,display_area_enable,reset;
output reg one_bit_output;
output reg [2:0]counter;
always #(posedge vga_clk or posedge reset)
begin
if (reset)
begin
counter=3'd7;
one_bit_output=0;
end
else if (display_area_enable==1)
begin
one_bit_output<=(char_rom_data_out[counter]==1);
counter<=counter-1;
end
else if (display_area_enable==0)
begin
counter<=3'd7;
one_bit_output<=0;
end
end
endmodule
module testbz();
reg reset,vga_clk,display_area_enable;
reg [7:0]char_rom_data_out;
wire [2:0] counter;
wire one_bit_output;
shifter dignitas(reset,char_rom_data_out,vga_clk,display_area_enable,one_bit_output,counter);
initial
begin
reset<=1; char_rom_data_out<=8'b11110001; vga_clk<=0;display_area_enable=0; //sto 10 skaei o prwtos kyklos, kai meta ana 20
#5 reset<=0; display_area_enable<=0;
#5 display_area_enable<=1;
#160 display_area_enable<=0;
end
always
begin
#10 vga_clk=~vga_clk;
end
endmodule
and the simulation is :
Can someone explain to me why on the first pulse of the vga_clk, the output is not expected?
Change one_bit_output so that it does not change in relation to the clock edge, but asynchronously in relation to the display_area_enable. The counter keeps track of which element to output. This is essentially a multiplexer with display_area_enable as the selector, or more likely an AND gate with one input being display_area_enable.
As toolic said, the synchronous one_bit_output cannot change on the same cycle as its activating signal. This is because of the set-up times of the flip-flops, the signal must be stable for some time before the clock edge. Now, if you are using one_bit_output to drive some flip-flop, then it MUST update on the next edge. Don't try to avoid this by using latches, that will make synthesis quite hard.
module shifter(reset,char_rom_data_out,vga_clk,display_area_enable,one_bit_output,counter);
input [7:0]char_rom_data_out;
input vga_clk,display_area_enable,reset;
output reg one_bit_output;
output reg [2:0]counter;
always #(posedge vga_clk or posedge reset)
begin
if (reset)
begin
counter<=3'd7;
//one_bit_output<=0;
end
else if (display_area_enable==1)
begin
//one_bit_output<=(char_rom_data_out[counter]==1);
counter<=counter-1;
end
else if (display_area_enable==0)
begin
counter<=3'd7;
//one_bit_output<=0;
end
end
assign one_bit_output = display_area_enable ? char_rom_data_out[counter] : 0;
endmodule

1second down counter with initial value verilog code

I want to write the code of 1-second down counter that get the initial value from outside and count it down till 0. but there is a problem. How can I get the initial value. i tried some ways but ....
here is the code:
module second_counter ( input clk,
input top_num,
output reg [3:0] sec_num
);
parameter clk_frequency = 25;
reg [31:0]cnt;
wire [3:0]sec;
/// how can get the top_num and count it down.
assign sec=top_num;
always #(posedge clk)
begin
if (cnt==clk_frequency)
begin
sec <= sec -1;
cnt<=0;
end
else
cnt <=cnt+1;
end
What you basically need is a reset signal. Just like clock, reset is to be added in the sensitivity list.
After instantiation of module, you must apply a reset signal to initialize all the internal variables and registers of design.
Following code gives you initial value of cnt by reset application. This is an active low reset.
module second_counter ( input clk, input reset, input top_num, output reg [3:0] sec_num );
parameter clk_frequency = 25;
reg [31:0]cnt;
// wire [3:0]sec;
reg [3:0] sec;
///
// assign sec=top_num;
always #(posedge clk, negedge reset)
begin
if(!reset)
begin
cnt<=0; // initialize all internal variables and registers
sec<=0;
end
else
begin
if(sec == 0) // latch input when previous count is completed
sec<=top_num;
if (cnt==clk_frequency)
begin
sec <= sec -1;
cnt<=0;
end
else
cnt <=cnt+1;
end
end
Note that this is an asynchronous reset, means it does not depend on clocking signal. Synchronous reset is the one which only affects the registers at the clock pulse.
Edit:
Regarding to sec, I have modified the code. Now the design latches the inputs for one clock cycle and counts down to zero. Once the counter reaches zero, it again latches the input to re-count to zero.
Note that you cannot do like latching top_num at every clock and counting through zero (since top_num can change at every pulse). For latching at every clock pulse, you need more complex logic implementation.

Monitor statement verilog

Removing #2 reset after monitor statement makes the code not to work.The output just stands at 0 x. Whereas including it works fine. Why?
module counter(out,clock,reset);
input clock,reset;
wire clock,reset;
output [3:0]out;
reg [3:0]out;
always #(posedge clock or negedge clock)
begin
if(reset)
out<=1'b0;
else
out<=out+1;
end
endmodule
module tb();
reg clock,reset;
output [3:0]out;
counter c(out,clock,reset);
initial
begin
clock=0;
reset=1;
end
initial
begin
$monitor("%d %d",$time,out);
#2 reset=0;
end
always
#1 clock=~clock;
initial
#100 $finish;
endmodule
By removing the #2 you create a race condition on reset:
initial reset = 1;
initial reset = 0;
Simulators will often have the the final value of reset the last assignment read in the compiling order. Try merging you initial blocks:
initial
begin
$monitor("%d %d",$time,out);
clock=0;
reset=1;
#2 // <-- optional (and still recommened) if you make the below change
// #(clk) //<-- if you truely want a dual edge triggered flip-flop with synchronous reset
reset=0;
end
Dual edge triggered flip-flop are very uncommon and many synthesizers and FPGAs do not support them. I'm guessing you are intending to have an negative edge triggered flip-flop with an active high asynchronous reset. In this case replace:
always #(posedge clock or negedge clock)
with:
always #(negedge clock or posedge reset)

Shifting a Concatenate Register

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.

Resources