In our previous post, we discussed about general codes for some of the most important combinational blocks. In this post, we will discuss general Verilog codes for some of the most important sequential blocks. General Verilog Codes for Sequential Blocks are important to avoid different codes for different design parameters. General Verilog codes make our job easy to write very complex code in a structural style. Here, general verilog code for register, counter are discussed. User can easily write general codes for other blocks.
General Register Block
In a register, data-width is the main parameter that can be varied. Thus data-width can be considered as ‘parameter‘. The general code can take any value of the data-width. If the width is 1 then it will become a simple D flip-flop. The code is as follows
module regN #(parameter N=18)(y,clk,reset,a);
input [N-1:0] a;
output reg [N-1:0] y;
input clk,reset;
always @(posedge clk)
if (reset)
y <= 0;
else
y <= a;
endmodule
General Delay Block
A general delay block is very useful when in a complex design, we need different kinds of delays. In some stages, we may need a delay of 4 clock cycles, and in another stage, we may need a delay of 9 clock cycles. Thus we should not write separate modules. Again, we may be required to delay a single-bit signal or multi-bit signal. The general delay block is shown below
module general_delay_block #(parameter N=1,
parameter D = 4)(clk,reset,a,aN);
input clk,reset;
input [N-1:0] a;
output [N-1:0] aN;
wire [N-1:0] tmp [D:0];
assign tmp[0] = a;
generate
genvar p;
for (p = 1; p <= D; p = p+1) begin: General_delay
regN #(N) rg(tmp[p],clk,reset,tmp[p-1]);
end
endgenerate
assign aN = tmp[D];
endmodule
The module regN is defined previously and it is used here to realize the general delay block. If we need a delay of 4 clock cycles then we will require 4 regN blocks. The command ‘generate‘ will generate 4 regN blocks if the value of parameter D is 4. The module generation will be done based on one variable called ‘p’ using ‘genvar‘ command. One thing we should keep in mind is that the name of genvar variable and the name of the parameters should not be the same. If one parameter name is N and genvar variable is n, then the code will synthesize the actual desired structure.
General Counter Block
General counter block is also required sometimes in complex design so that one verilog code can be used everywhere. A general counter block is written below. This counter can be implemented as up counter and also implemented as down counter also. Remember, the ‘generate’ command either generate hardware for up counter or down counter. But not for both. But this counter can not be used in design where we may require both kinds of counters.
module General_Counter #(parameter N = 10, up = 0)
(count,data,load,en,clk,reset,tc,lmt
);
output [N-1:0] count;
output tc;
input [N-1:0] data,lmt;
input load, en, clk,reset;
generate
case(up)
1'b0 : counterupN #(N) u0(count,data,load,en,clk,reset,tc,lmt);
1'b1 : counterdnN #(N) u1(count,data,load,en,clk,reset,tc,lmt);
endcase
endgenerate
endmodule
module counterupN #(parameter N = 10)(count,data,load,en,clk,reset,tc,lmt);
output [N-1:0] count;
output reg tc;
input [N-1:0] data,lmt;
input load, en, clk,reset;
reg [N-1:0] count;
always @(posedge clk)
if (reset) begin
count <= 1'b0 ;
end else if (load) begin
count <= data;
end else if (en)
count <= count + 1'b1;
else count <= count;
always @*
if (count ==lmt)
tc=1;
else tc=0;
endmodule
module counterdnN #(parameter N = 10)(count,data,load,en,clk,reset,tc,lmt);
output [N-1:0] count;
output reg tc;
input [N-1:0] data,lmt;
input load, en, clk,reset;
reg [N-1:0] count;
always @(posedge clk)
if (reset) begin
count <= 1'b0 ;
end else if (load) begin
count <= data;
end else if (en)
count <= count - 1'b1;
else count <= count;
always @*
if (count ==lmt)
tc=1;
else tc=0;
endmodule