Ошибка при создании модуля, который реализует файл регистра, который выполняет вычитание вектора (Verilog) - PullRequest
0 голосов
/ 27 марта 2020

Я очень новичок в Verilog, и мне было поручено создать модуль, который реализует файл регистров с функцией вычитания. У меня есть базовая c идея (я думаю), я знаю, что мне нужно сделать это, предоставив вывод пакета XOR gate в качестве второго операнда сумматора и Cary-In, который равен 1 (высокий или истинный) ) когда операция вычитание и 0 (низкий или ложный), когда это что-то еще. Я не знаю, как это сделать. Любая помощь будет оценена.

Вот что у меня есть:

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

Однако, когда я запускаю тестовый стенд, вычитание не работает, вместо этого я получаю 'x' вместо действительного значения. Кроме того, тактовый цикл не повторяется три раза. Dout выплевывает 'x' вместо значений.

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

Это тестовая среда:

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
...