Я очень новичок в 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