Verilog: Store counter value when reset is asserted - verilog

I have the following verilog code. Idea is to store value of counter at the time of reset. However, I am not sure if it would be synthesizable(memories need synchronous reset). I get DRC violatins and the memory, bufreadaddr, bufreadval are all optimized out. What are some other ways to write this?
module counter (clk,reset, d_out,laststoredvalue, bufreadaddr, bufreadval, resetcount) ;
input clk ,reset ;
input [5:0] resetcount;
output [15:0] d_out;
output [15:0] laststoredvalue;
input [5:0] bufreadaddr;
output [15:0] bufreadval;
reg [15:0] bufreadval;
reg [15:0] laststoredvalue;
reg [15:0] d_out;
reg [15:0] d_out_mem[63:0];
always #(negedge reset or posedge clk) begin
if (reset == 0) begin
d_out <= 16'h0000;
d_out_mem[resetcount] <= d_out;
laststoredvalue <= d_out;
end else begin
d_out <= d_out + 1'b1;
end
end
always #(bufreadaddr)
bufreadval = d_out_mem[bufreadaddr];
integer count;
initial begin
count = 0;
end
always #(posedge clk ) begin
count = count + 1;
//$display(count);
end
endmodule

hi i have made a small change for your code; added a temporary variable to store the output in a register it will store previous value on reset;
module counter (clk,reset, d_out,laststoredvalue, bufreadaddr, bufreadval, resetcount) ;
input clk ,reset ;
input [5:0] resetcount;
output [15:0] d_out;
output [15:0] laststoredvalue;
input [5:0] bufreadaddr;
output [15:0] bufreadval;
reg [15:0] bufreadval;
reg [15:0] laststoredvalue;
reg [15:0] temp;
reg [15:0] d_out;
reg [15:0] d_out_mem[63:0];
always #(negedge reset or posedge clk) begin
if (reset == 0) begin
d_out_mem[resetcount] = d_out;
laststoredvalue = temp;
d_out = #10 16'h0000;
end
else begin
d_out = d_out + 1'b1;
temp = d_out;
end
end
always #(bufreadaddr)
bufreadval = d_out_mem[bufreadaddr];
endmodule
remaining code is same as it is.

Related

Delay a 32-bit signal with N clock cycle in verilog

I am trying to delay a 32-bit signal using shift register. My logic is a single flip flop delay a signal by 1 clk so I use shift register as it is combination of flip flop can someone guide me what is wrong with this code.
module delay_n_cycles (
input wire [31:0] data_in,
input wire clk,
output reg [31:0] data_out,
parameter N = 5
);
reg [31:0] shift_reg;
always #(posedge clk) begin
shift_reg <= {shift_reg[30:0], data_in};
if (N == 0) begin
data_out <= shift_reg[31];
end else begin
data_out <= shift_reg[N-1];
end
end
endmodule
First of all, your code is syntactically wrong. parameter cannot be declared in a way you provided.
Your shift register is only 32 bit wide. Usually, to delay multi-bit data this way, you need to keep N copies of data in the register, shift them at one end and read at the other. I guess the following should help:
module delay_n_cycles #(parameter N = 5)(
input wire [31:0] data_in,
input wire clk,
output reg [31:0] data_out
);
reg [N-1:0][31:0] shift_reg;
always #(posedge clk) begin
shift_reg <= (shift_reg << 32) | data_in;
data_out <= shift_reg[N-1];
end
endmodule
This code will work with system verilog because it used packed multi-dimensional arrays.
You need to shift the reg by 32 (width of the data) in packed version.
Here is an example of a testbench:
module tb();
bit clk;
int clkCount;
initial
forever begin
#5 clk = ~clk;
clkCount++;
end
logic [31:0] data_in, data_out;
initial begin
$monitor("%0t (%0d) [%h]: %0d --> %0d", $time, clkCount, ds.shift_reg[4], data_in, ds.data_out);
for(int i = 0; i < 20; i++) begin
#10 data_in = i;
end
$finish;
end
delay_n_cycles ds(data_in, clk, data_out);
endmodule

Clock Divider for 50MHz to 1MHz - Verilog

I have written the code for SPI Master and I want the output SPI frequency to be 1MHz.
But, when I run the behaviroal simulation, I don't get a 1MHz spi_sclk. Any suggestions what is wrong with my code? Thanks!
module spi_master(
input wire clk,
input wire reset,
input wire [15:0] datain,
output wire spi_cs_l,
output wire spi_sclk,
output wire spi_data,
output wire [4:0] counter
);
reg [15:0] MOSI;
reg [4:0] count;
reg cs_l;
reg sclk = 1'b0;
reg [2:0] state;
reg [4:0] clk_counter = 0;
// SPI Output Clock frequency = 1MHz
always #(posedge clk) begin
if (clk_counter == 24) begin
clk_counter <= 0;
sclk <= ~sclk;
end
else begin
clk_counter <= clk_counter + 1'd1;
end
end
always #(posedge clk or posedge reset) begin
if(reset) begin
MOSI <= 16'b0;
count <= 5'd16;
cs_l <= 1'b1;
end
else begin
case (state)
0:begin
cs_l <= 1'b1;
state <= 1;
end
1:begin
cs_l <= 1'b0;
MOSI <= datain[count-1];
count <= count-1;
state <= 2;
end
2:begin
if(count > 0) begin
state <= 1;
end
else begin
count <= 16;
state <= 0;
end
end
default:state<=0;
endcase
end
end
assign spi_cs_l = cs_l;
assign spi_sclk = sclk;
assign spi_data = MOSI;
assign counter = count;
endmodule
Testbench
module spi_master_tb;
// Inputs
reg clk;
reg reset;
reg [15:0] datain;
// Outputs
wire spi_cs_l;
wire spi_sclk;
wire spi_data;
wire [4:0] counter;
spi_master dut(
.clk(clk),
.reset(reset),
.counter(counter),
.datain(datain),
.spi_cs_l(spi_cs_l),
.spi_sclk(spi_sclk),
.spi_data(spi_data)
);
initial begin
clk = 0;
reset = 1;
datain = 0;
end
always #5 clk=~clk;
initial begin
#10 reset = 1'b0;
#10 datain = 16'hA569;
#335 datain = 16'h2563;
#335 datain = 16'h9B63;
#335 datain = 16'h6A61;
end
endmodule
Waveform
It helps if you create Minimal reproducible example. Also your waveform don't include an important signal clk_counter.
Try this in your testbench, if it doesn't work you at least have the minimum reproducible example.
I changed the initialization of clk_counter and in the increment I simply added 1 instead of 1'b1, if you wanted to be strict you could add a 5-bit wide 1 (5'b1).
module spi_master(
input wire clk,
input wire reset,
output wire spi_sclk,
);
reg [4:0] clk_counter;
// SPI Output Clock frequency = 1MHz
always #(posedge clk) begin
if(reset) begin
sclk <= 1'b0;
clk_counter <= 1;
end
else begin
if (clk_counter == 24) begin
clk_counter <= 0;
sclk <= ~sclk;
end
else begin
clk_counter <= clk_counter + 1;
end
end
end
assign spi_sclk = sclk;
endmodule

How to add clock in Xilinx/Verilog

I am new in Xilinx.
Here's my code,and i want to add clock in it.
Please tell me how to add clock. Thanks
code
module Traffic(
output reg red1,
output reg red2,
output reg red3,
output reg red4,
output reg yel1,
output reg yel2,
output reg yel3,
output reg yel4,
output reg gr1,
output reg gr2,
output reg gr3,
output reg gr4,
input [1:0] c1,
input [1:0] c2
);
always #(c1,c2,red1,red2,red3,red4,yel1,yel2,yel3,yel4,gr1,gr2,gr3,gr4)
begin
case({c1,c2})
4'b0000:begin red1=0;red2=1;red3=1;red4=0; yel1=1;yel2=0;yel3=0;yel4=1; gr1=0;gr2=0;gr3=0;gr4=0; end
4'b0001:begin red1=1;red2=1;red3=1;red4=0; yel1=0;yel2=0;yel3=0;yel4=0; gr1=0;gr2=0;gr3=0;gr4=1; end
4'b0010:begin red1=0;red2=1;red3=1;red4=0; yel1=1;yel2=1;yel3=0;yel4=0; gr1=0;gr2=0;gr3=0;gr4=0; end
4'b0011:begin red1=1;red2=1;red3=1;red4=1; yel1=0;yel2=0;yel3=0;yel4=0; gr1=0;gr2=1;gr3=0;gr4=0; end
4'b0100:begin red1=1;red2=0;red3=0;red4=1; yel1=0;yel2=1;yel3=1;yel4=0; gr1=0;gr2=0;gr3=0;gr4=0; end
4'b0101:begin red1=1;red2=1;red3=0;red4=1; yel1=0;yel2=0;yel3=0;yel4=0; gr1=0;gr2=0;gr3=1;gr4=0; end
4'b0110:begin red1=1;red2=1;red3=0;red4=0; yel1=0;yel2=0;yel3=1;yel4=1; gr1=0;gr2=0;gr3=0;gr4=0; end
4'b0111:begin red1=1;red2=1;red3=1;red4=0; yel1=0;yel2=0;yel3=0;yel4=0; gr1=0;gr2=0;gr3=0;gr4=1; end
endcase
end
endmodule
-------------
Text Fixture
-------------
module tf;
// Inputs
reg [1:0] c1;
reg [1:0] c2;
// Outputs
wire red1;
wire red2;
wire red3;
wire red4;
wire yel1;
wire yel2;
wire yel3;
wire yel4;
wire gr1;
wire gr2;
wire gr3;
wire gr4;
// Instantiate the Unit Under Test (UUT)
Traffic uut (
.red1(red1),
.red2(red2),
.red3(red3),
.red4(red4),
.yel1(yel1),
.yel2(yel2),
.yel3(yel3),
.yel4(yel4),
.gr1(gr1),
.gr2(gr2),
.gr3(gr3),
.gr4(gr4),
.c1(c1),
.c2(c2)
);
initial begin
c1 = 2'b00;c2 = 2'b00;
#100 c1 = 2'b00;c2 = 2'b01;
#100 c1 = 2'b00;c2 = 2'b10;
#100 c1 = 2'b00;c2 = 2'b11;
#100 c1 = 2'b01;c2 = 2'b00;
#100 c1 = 2'b01;c2 = 2'b01;
#100 c1 = 2'b01;c2 = 2'b10;
#100 c1 = 2'b01;c2 = 2'b11;
end
If I understand your question correctly, you would like the outputs of your module to be synchronous to a clock. you need to declare the clock as in input wire, and alter the always block to use the posedge clk. It's also good to add a reset -- you can have a synchronous reset or an asynchronous reset. Here's how such a block would be structured, with an asynchronous reset:
module Traffic(
input wire clk,
input wire resetb, // negative edge asynchronous reset
output reg red1,
output reg red2,
output reg red3,
output reg red4,
output reg yel1,
output reg yel2,
output reg yel3,
output reg yel4,
output reg gr1,
output reg gr2,
output reg gr3,
output reg gr4,
input [1:0] c1,
input [1:0] c2
);
always #(posedge clk or negedge resetb)
begin
if (!resetb) begin
red1 <= 'd0;
// etc....
end else begin
case({c1,c2})
4'b0000:begin
red1<=0;red2<=1;red3<=1;red4<=0;
yel1<=1;yel2<=0;yel3<=0;yel4<=1;
gr1<=0;gr2<=0;gr3<=0;gr4<=0;
end
4'b0001:begin
red1<=1;red2<=1;red3<=1;red4<=0;
yel1<=0;yel2<=0;yel3<=0;yel4<=0;
gr1<=0;gr2<=0;gr3<=0;gr4<=1;
end
// etc...
endcase
end
end
endmodule

calculate how many times input is repeated verilog

I'm trying to calculate times in which input x with 8 bits is repeated on every posedge clk.
I'm thinking about creating 256b counter to each value of these 8 bit to compare x with it, but I get error when I'm trying to compare each value of these counter with each input x on rising edge.
module counter_initial(x);
input[7:0] x;
//output [7:0] y;
//reg [7:0] y;
//reg [7:0] freq_tst,gap_tst;
reg [7:0] freq_num;
endmodule
module counter_256(clk,x,out);
input [7:0] x;
input clk;
// input [7:0] in;
output [7:0] out;
reg [7:0] out;
//reg [7:0] freq_tst,gap_tst;
reg [7:0] k=0;
// reg [] t=0;
genvar i;
generate
for (i=0;i<256;i=i+1)
begin
counter_initial m(i);
//t=m(i);
end
endgenerate
always #(posedge clk)
begin
if(k<256) begin
if (x==m[i])
//counter_initial[k]==x
begin
freq_num=freq_num+1;
end
//else
//begin gap_tst=gap_tst+1; end
k=k+1;
end
end
endmodule
You don't need an additional module to count. You can use a memory array. Example:
input [WIDTH-1:0] x;
reg [7:0] mem [WIDTH-1:0];
integer i;
always #(posedge clk) begin
if (reset) begin
for (i = 0; i < 2**WIDTH; i = i+1) begin
mem[i] <= 8'b0;
end
end
else if (mem[x] < 8'd255) begin // cap counting and prevent overflow
mem[x] <= mem[x] + 1'b1;
end
end
If you want to use separate modules then pass the clock to it. Example:
module counter (output reg [7:0] count, input increment, clk, reset);
always #(posedge clk) begin
if (reset) begin
count <= 8'b0;
end
else if (count < 8'd255) begin // cap counting and prevent overflow
count <= count + increment;
end
end
endmodule
module my_device ( /* ..., */ input [7:0] x, input clk, reset );
/* ... */
genvar i;
generate
for (i=0; i<256; i=i+1) begin
counter icount( .count(/* ... */), .increment(x==i), .* );
end
endgenerate
/* ... */
endmdoule
Reminder 8'd255 + 1 is 8'd0 because the MSB of 8'd256 is out of range. I capped the counters so the will not overflow and roll back to zero.

malformed statement in verilog

Hi i am using the folowing code to design a n-bit counter.
Depending on the start and end i want to instantiate up or down counter.
But i am getting "Malformed statement". Please help.
module nbitUpCounter(startc,endc , clk, rst_n,actlow,count);
parameter n = 7;
output reg [n:0] count;
input [n:0] startc;
input [n:0] endc;
input clk;
input rst_n;
input actlow;
// Increment count on clock
always #(actlow or posedge clk or negedge rst_n)
begin
if (actlow == 0)
begin
if (rst_n==0)
count = startc;
else if (count==endc) count=startc;
else count = count + 1;
end
end
endmodule
module nbitDownCounter(startc,endc , clk, rst_n,actlow,count);
parameter n = 7;
output reg [n:0] count;
input [n:0] startc;
input [n:0] endc;
input clk;
input rst_n;
input actlow;
// Increment count on clock
always #(actlow or posedge clk or negedge rst_n)
begin
if (actlow == 0)
begin
if (rst_n==0)
count = startc;
else if (count==endc) count=startc;
else count = count - 1;
end
end
endmodule
module Init(startc,endc , clk, rst_n,actlow,count);
parameter n = 7;
output wire [n:0] count;
input [n:0] startc;
input [n:0] endc;
input clk;
input rst_n;
input actlow;
generate
initial
begin
if(startc>endc)
nbitDownCounter c(startc, endc, C_t,rst_t,actlow,count);
end
endgenerate
endmodule
module Testbench;
reg [7:0] startc, endc;
reg C_t, rst_t;
reg actlow;
wire [7:0] outc;
initial
begin
//case 0
startc <= 8'b00000011; endc <= 8'b0000001;
//Init i(startc,endc,C_t,rst_t,actlow,count);
actlow<=0;
C_t <=1; rst_t <=0;
#1 $display("count = %b",outc );
//case1
rst_t<=1;C_t<=0;C_t<=1;
#1 $display("count = %b",outc );
//Case3
C_t<=0;C_t<=1;
#1 $display("count = %b",outc );
//Case3
C_t<=0;C_t<=1;
#1 $display("count = %b",outc );
end
endmodule
You're trying to instantiate your module in an initial block, which is illegal. Removing the initial begin inside module Init should solve the problem. Have a look at this page for an example: http://asic-soc.blogspot.de/2012/06/verilog-hdl-generate-blocks.html

Resources