0
\$\begingroup\$

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?

enter image description here

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ You just dumped a load of code here and haven't asked any question \$\endgroup\$ – Eugene Sh. Jun 4 '16 at 3:18
  • \$\begingroup\$ I am sorry about my post being confusing. My question is why is my counter starts counting before Finishing circuit initialization process. \$\endgroup\$ – Ashutosh Jain Jun 4 '16 at 3:30
  • 1
    \$\begingroup\$ Show what you expect to observe, or some waves of the relevant module... \$\endgroup\$ – Sean Houlihane Jun 4 '16 at 11:50
  • \$\begingroup\$ @SeanHoulihane So one of the most prominent error that I can point out is my Counter starts counting before Initialization process finishes, and therefore the modules are not synchronized properly. \$\endgroup\$ – Ashutosh Jain Jun 4 '16 at 20:58
  • \$\begingroup\$ One small point, you have initial blocks replicating the work of the reset - this is probably harmless, but not necessary. You only need initial to drive CLK and RESETn, everything else can be driven from them. If I read you right, you want to sample the first result when COUNTER==0? This should be happening already, its just your display don't have any defined ordering. If you capture the result in a flop, you might get the result you want. \$\endgroup\$ – Sean Houlihane Jun 5 '16 at 15:09
1
\$\begingroup\$

It looks like you hold the clock low whilst reset is low. This may prevent some stages from resetting properly (there is neither a posedge CLK or negedge RESETn). Notice that top reset doesn't appear in your output. Generally in a real-world power-on sequence, voltage stabilises, clock will be started, and once it is stable and applied to the circuit, reset is de-asserted.
Some circuits explicitly require a number of clock cycles of reset asserted (LOW) in order to initialise pipelines, etc.

// Add stimulus here 
always begin 
 // if   (RESETn == 1'b0) 
//      begin CLK = 0; not needed
//       RESETn = 1;  not needed
 // end else  
 #10 CLK = ~CLK; 
end
\$\endgroup\$
  • \$\begingroup\$ Thanks @SeanHoulihane for the input, I made a change put putting RESETn = 0 during initialization and then RESETn = 1 after the Global Delay, but nothing much changes. Should I increase the global delay or I need to do something else? \$\endgroup\$ – Ashutosh Jain Jun 4 '16 at 21:02
  • \$\begingroup\$ See my edit. I think you actually deassert reset earlier than you want to. \$\endgroup\$ – Sean Houlihane Jun 4 '16 at 22:43
  • \$\begingroup\$ as per your code should I initialize the reset in initial as 0 or 1. If 0, then where should i make it 1, otherwise the code won't run at all. \$\endgroup\$ – Ashutosh Jain Jun 4 '16 at 23:14
  • \$\begingroup\$ Reset start low, clock low, clock high, clock low, reset high. Other combinations are valid, but that should work. Reset looks like it goes high in your initial block at 50 cycles. \$\endgroup\$ – Sean Houlihane Jun 4 '16 at 23:17
  • \$\begingroup\$ Do you mean like this? initial begin RESETn = 0; CLK = 0; #10 CLK = 1; #10 CLK = 0; #100 RESETn = 1; end always begin if (RESETn == 1'b0) begin //CLK = 0; //RESETn = 1; end else #10 CLK = ~CLK; end \$\endgroup\$ – Ashutosh Jain Jun 5 '16 at 5:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.