I have been trying to learn verilog with help of a project. The mix that takes adder output as input and gives input to adder as per the control signal is going into an infinite loop, but it should only add till count = 9 and then reset. Can someone please point out my mistake?
Top Module
`timescale 1ns / 1ps
module top(
input CLK,
input RESETn,
input [9:0] imgPixel,
output [15:0] WORD_OUT
);
reg [3:0] counter;
wire select_in_mx1,select_out_mx1,select_in_mx2,select_out_mx2;
wire [15:0] out_csr,in_mx0,out_mx0,in_mx1,out_mx1,in1_mx2,in2_mx2,out_mx2,in1_add0,in2_add0,out_add0;
// Instantiate the Unit Under Test (UUT)
cir_shift_reg_v csr (
.CLK(CLK),
.RESETn(RESETn),
.WORD_OUT(out_csr)
);
assign in_mx0 = out_csr;
mux mx0 (
.WORD_IN1(in_mx0),
.WORD_IN2(16'd0),
.SELECT_BIT_IN(imgPixel[count_out]),
.WORD_OUT(out_mx0)
);
assign in1_add0 = out_mx0;
counter cnt0 (
.CLK(CLK),
.RESETn(RESETn),
.count(count_out)
);
assign count_in = count_out;
control crtl0 (
.counter(count_in),
.condition(4'd0),
.SELECT_BIT_OUT(select_out_mx1)
);
assign select_in_mx1 = select_out_mx1;
//assign in_mx1 = out_add0;
mux mx1 (
.WORD_IN1(16'd0),
.WORD_IN2(in_mx1),
.SELECT_BIT_IN(select_in_mx1),
.WORD_OUT(out_mx1)
);
assign in2_add0 = out_mx1;
adder add0 (
.count(count_in),
.WORD_IN1(in1_add0),
.WORD_IN2(in2_add0),
.WORD_OUT(out_add0)
);
assign in1_mx2 = out_add0;
assign in_mx1 = out_add0;
control crtl1 (
.counter(count_in),
.condition(4'd9),
.SELECT_BIT_OUT(select_out_mx2)
);
assign select_in_mx2 = select_out_mx2;
assign in2_mx2 = out_mx2;
mux mx2 (
.WORD_IN1(in1_mx2),
.WORD_IN2(in2_mx2),
.SELECT_BIT_IN(select_in_mx2),
.WORD_OUT(out_mx2)
);
assign WORD_OUT = out_mx2;
endmodule
Circular Shift Register Module
`timescale 1ns / 1ps
module cir_shift_reg_v(
input CLK,
input RESETn,
output reg [15:0] WORD_OUT
);
parameter initialValue = {16'h0,16'h1,16'h2,16'h3,16'h4,16'h5,16'h6,16'h7,16'h8,16'h9};
//This works because concatenation makes it a 160bit wide value.
reg [15:0] wordShiftReg[9:0];
integer i;
initial begin
for (i=0;i<10;i=i+1) begin
wordShiftReg[i] = initialValue[((9-i)*16)+:16];
end
end
always @(posedge CLK or negedge RESETn) begin
if (RESETn == 1'b0) begin
for (i=0;i<10;i=i+1)
wordShiftReg[i] <= initialValue[((9-i)*16)+:16];
end
else begin
WORD_OUT = wordShiftReg[0];
for (i=0;i<9;i=i+1) begin
wordShiftReg[i] <= wordShiftReg[i+1];
end
wordShiftReg[9] <= WORD_OUT;
end
$display ("CSR op = %d",WORD_OUT);
end
endmodule
Multiplexer Module
`timescale 1ns / 1ps
module mux(
input [15:0] WORD_IN1,
input [15:0] WORD_IN2,
input SELECT_BIT_IN,
output reg [15:0] WORD_OUT
);
always @(*) begin
$display ("SELECT BIT = %d", SELECT_BIT_IN);
$display ("WORD_IN1 = %d", WORD_IN1);
$display ("WORD_IN2 = %d", WORD_IN2);
WORD_OUT = (SELECT_BIT_IN) ? WORD_IN1 : WORD_IN2;
$display ("MUX op = %d",WORD_OUT);
end
endmodule
Counter Module
`timescale 1ns / 1ps
module counter(
input CLK,
input RESETn,
output reg [3:0] count
);
always @(posedge CLK or negedge RESETn) begin
if (RESETn == 1'd0) begin
count <= 4'd9;
end
else begin
count <= ((count + 4'd1)%10);
end
//$display ("count = %d",count);
end
endmodule
Control Module
`timescale 1ns / 1ps
module control(
input [3:0] counter,
input [3:0] condition,
output reg SELECT_BIT_OUT
);
always @(*) begin
$display ("Counter = %d", counter);
$display ("Condition = %d", condition);
SELECT_BIT_OUT = (counter==condition) ? 1'd1 : 1'd0;
$display ("CTRL op = %d",SELECT_BIT_OUT);
end
endmodule
Adder Module
`timescale 1ns / 1ps
module adder(
input [15:0] WORD_IN1,
input [15:0] WORD_IN2,
output reg [15:0] WORD_OUT
);
always @(*) begin
$display ("WORD_IN1 = %d", WORD_IN1);
$display ("WORD_IN2 = %d", WORD_IN2);
WORD_OUT = WORD_IN1 + WORD_IN2;
$display ("ADD op = %d",WORD_OUT);
end
endmodule
TestBench
`timescale 1ns / 1ps
module tb_top;
// Inputs
reg CLK;
reg RESETn;
reg [9:0] imgPixel;
// Outputs
wire [15:0] WORD_OUT;
// Instantiate the Unit Under Test (UUT)
top uut (
.CLK(CLK),
.RESETn(RESETn),
.imgPixel(imgPixel),
.WORD_OUT(WORD_OUT)
);
initial begin
// Initialize Inputs
RESETn = 0;
CLK = 0;
#10 CLK = 1;
#10 CLK = 0;
// Wait 100 ns for global reset to finish
//#100;
#20 RESETn = 1;
imgPixel = 10'b1000111010;
end
// Add stimulus here
always begin
//if (RESETn == 1'b0) begin
//CLK = 0;
//RESETn = 1;
//end
//else
#10 CLK = ~CLK;
end
// monitor results
always @(negedge CLK)
$display("TOP op = %d\n",WORD_OUT);
endmodule
Please point out any good practices and anything else that should be changed. Thanks in advance.
