Error while creating a module that implements a register file that does vector subtraction (Verilog)

风流意气都作罢 提交于 2020-04-18 03:46:55

问题


I am very new to Verilog and I have been given a task to create a module that implements a register file with subtraction functionality. I do have an basic idea (I think) I do know that I need to do this by supplying the output of a XOR gate bundle as the second operand of the adder and a cary-in that is 1 (high or true) when the operation is subtraction and 0 (low or false) when it is anything else. I dont know how to do this. Any help would be appreciated.

Here is what I have so far:

module gvectorRF(Dout, RS1, RS2, RD, WDATA, cntstart, op, clk, reset);
parameter SIZE = 128;
parameter WINBITS = 2;
parameter WIDTH = 32;

localparam IDLE = 3'b000;
localparam VADD = 3'b001;
localparam VIN  = 3'b010;
localparam VOUT = 3'b011;
localparam VSUB = 3'b100;
localparam VMUL = 3'b101;
localparam VMULH= 3'b110;

output [WIDTH-1:0]  Dout;
input [4:0]            RS1, RS2, RD;
input [WIDTH-1:0]   WDATA;
input [WINBITS-1:0] cntstart;
input [1:0]            op;
input              clk, reset;
wire [WIDTH-1:0]    RD1, RD2, muxout, addout;
wire               uncon;
wire [WINBITS-1:0]  cntout;
reg [1:0]          cntrctl;
reg [1:0]          state;

winrf  #(.SIZE(SIZE), .WINBITS(WINBITS+5), .WIDTH(WIDTH))
vecwinrf(RD1, RD2, RS1, RS2, RD, muxout, {cntout, 5'b0}, clk, 
    /*
     * ( (state==IDLE)&&((op==VIN)||(op==VADD)) )||
     */
    ((state==VIN)||(state==VSUB))
    );
assign Dout = RD1;
yAdder #(WIDTH) vecadder(addout, uncon, RD1, RD2, 1'b0);
yMux #(WIDTH) vecmux(muxout, addout, WDATA, (state!=VADD));
cntr #(WINBITS) veccntr(cntout, Zout, cntstart, cntrctl, clk, reset);

always @(posedge reset)
  state = IDLE;

always @(posedge clk)
  begin
 case (state)
   IDLE: 
     state <= op;
   default : if (Zout==1'b1)
     state <= IDLE;
 endcase // case (state)
 /* We can put in here debugging code, but we delete it in the end
  * $display("state: %2b, Z=%1b, cntrctl = %2b, cntout = %2b", 
     state, Zout, cntrctl, cntout);
$display("addout = %d, vecwinrf[RS1=%d] = %d, vecwinrf[RS2=%d] = %d",
    addout,{cntout, 5'b0}+RS1, RD1, {cntout, 5'b0}+RS2, RD2);
 */
 end

always @(state)
 begin
case (state)
  IDLE:    cntrctl = 2'b01; // initialize cntr
  default: cntrctl = 2'b11; // decrement cntr
endcase // case (state)
 end
    endmodule

However when I run my testbench the subtraction does not work, instead I get an 'x' instead of the actual value. In addition, the clock cycle does not repeat three times. The Dout spits an 'x' instead of values.

WDATA =  36
WDATA = 129
WDATA =   9
WDATA =  99
WDATA =  13
Sec. inp. bundle
WDATA = 141
WDATA = 101
WDATA =  18
WDATA =   1
WDATA =  13
Compute bundle
Out bundle //issues from here to end.
Dout =   x
Dout =   x
Dout =   x
Dout =   x
Dout =   x //end

This is the testbench:

module testbench;
parameter TSTWIDTH = 8;

wire [TSTWIDTH-1:0] Dout;
reg [4:0]          RS1, RS2, RD;
reg [TSTWIDTH-1:0]  WDATA;
reg                clk, reset;
reg [2:0]          vecop;
integer            i;

gvectorRF #(.SIZE(128), .WINBITS(2), .WIDTH(TSTWIDTH))
tstvectorRF(Dout, RS1, RS2, RD, WDATA, 2'b11, vecop, clk, reset);


initial
  begin
    clk = 0;
vecop = 3'b010;     // INP
reset = 1;
RS1 = 5'b00000;
RS2 = 5'b00010;
RD  = 5'b00000;
#1;
reset = 0;
#1 repeat (5) 
  begin
     WDATA = $random & 255;
     $display("WDATA = %d",WDATA);
     #1 clk = 1; #1 clk = 0; #1;
     vecop = 3'b000;    // IDLE
  end
RD  = 5'b00010;
vecop = 3'b010;     // INP
$display("Sec. inp. bundle");
#1 repeat (5) 
  begin
     WDATA = $random & 255;
     $display("WDATA = %d",WDATA);
     #1 clk = 1; #1 clk = 0; #1;
     vecop = 3'b000;    // IDLE
  end
RD = 5'b00001;

vecop = 3'b001;     // VADD
vecop = 3'b101;     // VMUL
vecop = 3'b110;     // VMULH
vecop = 3'b100;     // VSUB

$display("Compute bundle");
#1 repeat (45) 
  begin
     #1 clk = 1; #1 clk = 0; #1;
     vecop = 3'b000;    // IDLE
  end
$display("Out bundle");
vecop = 3'b011;     // VOUT
RS1 = 5'b00001;
#1 repeat (5) 
  begin
     #1 clk = 1; #1 clk = 0; #1;
     vecop = 2'b00; // IDLE
     $display("Dout = %d",Dout);
  end

for (i=0; i<128; i=i+1)
  begin
     $display("R[%3d] = %3d", i, tstvectorRF.vecwinrf.rbank[i]);
  end
 end
  //   initial
  //     $monitor("%4d:  clk=%b, Dout= %3d, WDATA=%8d", 
  //          $time, clk,    Dout,     WDATA);

    endmodule

来源:https://stackoverflow.com/questions/60879069/error-while-creating-a-module-that-implements-a-register-file-that-does-vector-s

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!