I am trying use the output of a 16-bit encoder as to give input to the register (PIPO)

Viewed 146

I am trying use the output of a 16-bit encoder as to give input to the register(PIPO). The 16-bit encoder will give 4-bit binary output; these 4-bit binary output will be given as input to the register.

`timescale 1ps/1ps

module encoder16to4 (clk,en,encoder_in,encoder_out);

input clk,en;
input [15:0]encoder_in;
output reg [3:0] encoder_out;

always @(*) begin
    if(en)
        case(encoder_in)
        16'b0000000000000001 : encoder_out =4'b0000;
        16'b0000000000000010 : encoder_out =4'b0001;
        16'b0000000000000100 : encoder_out =4'b0010;
        16'b0000000000001000 : encoder_out =4'b0011;
        16'b0000000000010000 : encoder_out =4'b0100;
        16'b0000000000100000 : encoder_out =4'b0101;
        16'b0000000001000000 : encoder_out =4'b0110;
        16'b0000000010000000 : encoder_out =4'b0111;
        16'b0000000100000000 : encoder_out =4'b1000;
        16'b0000001000000000 : encoder_out =4'b1001;
        16'b0000010000000000 : encoder_out =4'b1010;
        16'b0000100000000000 : encoder_out =4'b1011;
        16'b0001000000000000 : encoder_out =4'b1100;
        16'b0010000000000000 : encoder_out =4'b1101;
        16'b0100000000000000 : encoder_out =4'b1110;
        16'b1000000000000000 : encoder_out =4'b1111;
        default: encoder_out = 3'bxxx;
        endcase
    else
        encoder_out= 3'b000;
end
 
endmodule

module PIPO (clk,reset,pipo_in,pipo_out);

input clk;
input reset;
input [3:0] pipo_in;
output reg [3:0] pipo_out;


always @(*) begin
    if (reset)
        pipo_out = 4'b0000;
    else
        pipo_out = pipo_in;
end

endmodule

Here is the test bench where i am trying to instantiated the above said

module tb;
reg clk;
reg en;
reg reset;
reg [15:0]encoder_in;
reg [3:0]encoder_out;
reg [3:0]pipo_in; 
wire [3:0]pipo_out;

encoder16to4 iencoder16to4(.clk(clk),.en(en),.encoder_in(encoder_in),.encoder_out(pipo_in));

initial begin
clk=0;
forever
#50 clk= ~clk;
end

initial begin
    $monitor("Time=%2t, Clock=%d, en=%b, in=%b, out=%b, pipo_in=%b, pipo_out=%b", $time, clk, en,encoder_in,encoder_out,pipo_in,pipo_out);
    $dumpfile("tb.vcd");
    $dumpvars(0,tb);
        
        clk=1;en=1;encoder_in=16'b0000000000000001;encoder_out =4'b0000;pipo_in=4'b0000;
        clk=1;en=1;encoder_in=16'b0000000000000010;encoder_out =4'b0001;pipo_in=4'b0001;
        clk=1;en=1;encoder_in=16'b0000000000000100;encoder_out =4'b0010;pipo_in=4'b0010;
        clk=1;en=1;encoder_in=16'b0000000000001000;encoder_out =4'b0011;pipo_in=4'b0011;
        clk=1;en=1;encoder_in=16'b0000000000010000;encoder_out =4'b0100;pipo_in=4'b0100;
        clk=1;en=1;encoder_in=16'b0000000000100000;encoder_out =4'b0101;pipo_in=4'b0101;
        
    $finish;
    end  

 
endmodule

This is the error I am getting in the terminal.

tb.v:12: error: reg pipo_in; cannot be driven by primitives or continuous assignment.
tb.v:12: error: Output port expression must support continuous assignment.
tb.v:12:      : Port 4 (encoder_out) of encoder16to4 is connected to pipo_in

Line 12

encoder16to4 iencoder16to4(.clk(clk),.en(en),.encoder_in(encoder_in),.encoder_out(pipo_in));

What correction should I do to make it work? Any help would be appreciated.

2 Answers

The error message tells you that you must not assign values to pipo_in in the testbench because you connected it to a module instance output. You also must not declare it as a reg; change it to a wire.

The same is true for the encoder_out testbench signal.

You also need to add an instance of the PIPO module.

You should not assign to clk in the initial block since you assign it in the always block.

You need to add delays to your inputs; for example, you can use posedge clk:

module tb;
reg clk;
reg en;
reg reset;
reg [15:0]encoder_in;
wire [3:0]encoder_out;
wire [3:0]pipo_in; 
wire [3:0]pipo_out;

encoder16to4 iencoder16to4(.clk(clk),.en(en),.encoder_in(encoder_in),.encoder_out(pipo_in));
PIPO PIPO (clk,reset,pipo_in,pipo_out);

initial begin
clk=0;
forever
#50 clk= ~clk;
end

initial begin
    $monitor("Time=%2t, Clock=%d, en=%b, in=%b, out=%b, pipo_in=%b, pipo_out=%b", $time, clk, en,encoder_in,encoder_out,pipo_in,pipo_out);
    $dumpfile("tb.vcd");
    $dumpvars(0,tb);
                
    @(posedge clk) en=1;encoder_in=16'b0000000000000001;
    @(posedge clk) en=1;encoder_in=16'b0000000000000010;
    @(posedge clk) en=1;encoder_in=16'b0000000000000100;
    @(posedge clk) en=1;encoder_in=16'b0000000000001000;
    @(posedge clk) en=1;encoder_in=16'b0000000000010000;
    @(posedge clk) en=1;encoder_in=16'b0000000000100000;
        
    $finish;
end  
 
endmodule

Please be attention that multiple drivers of variables is not allowed in verilog. In your testbench you have multiple driver on pipo_in, first in line 10 when you pass it to iencoder16to4 instance, and second one is when you assign value to it in lines [22-27], so you need remove one of these drivers.

You have other mistakes in your code:

  1. You do not need to re-assign 1 to clk in lines [22-27],because you already have clk generator in lines [12-15].
  2. In testbench we should drive the inputs and monitor the outputs, but note that in your testbench you also drive the output encoder_out in lines [22-27] and this is also consider mistake and you should remove it.
  3. The delays between inputs is missed in your testbench, so you should insert delays between them.
Related