我正在尝试使用 16 位编码器的输出作为寄存器 (PIPO) 的输入

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

我正在尝试使用 16 位编码器 的输出作为 register(PIPO) 的输入。 16位编码器将给出4位二进制输出;这些 4 位二进制输出将作为寄存器的输入。

`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

这是我尝试实例化上述内容的测试平台

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

这是我在终端中遇到的错误。

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

第 12 行

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

我应该做什么修正才能使其正常工作?任何帮助将不胜感激。

错误消息告诉您不能在测试台中为 pipo_in 赋值,因为您将它连接到模块实例输出。您也不得将其声明为 reg;将其更改为 wire.

encoder_out 测试台信号也是如此。

您还需要添加 PIPO 模块的实例。

您不应在 initial 块中分配给 clk,因为您在 always 块中分配它。

您需要为输入添加延迟;例如,您可以使用 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

请注意multiple drivers of variables is not allowed in verilog。在您的测试平台中,您在 pipo_in 上有多个驱动程序,当您将它传递给 iencoder16to4 instance 时,第一个在 line 10 中,第二个是当您在 lines [22-27] 中为其赋值时,所以您需要删除其中一个驱动程序。

您的代码中还有其他错误:

  1. 不需要 重新分配 1 to clk in lines [22-27],因为您已经在 lines [12-15].
  2. 中有了时钟生成器
  3. 在测试台中,我们应该驱动输入并监控输出,但请注意,在您的测试台中you also drive the output encoder_out in lines [22-27],这也是考虑错误和你应该删除它.
  4. 您的测试台中缺少输入之间的延迟,因此您应该在它们之间插入延迟。