瞬时模块无法正确执行减法

时间:2019-04-21 18:22:45

标签: verilog iverilog

我试图使用瞬时进位超前加法器在ALX为1且ALY为0时执行减法运算,但是它不能正常工作。可以很好地进行添加。

  • 如果ALX为0并且ALY也为0,则会将输入加载到输出中
  • 如果ALX为0而ALY为1,则会将输入添加到输出中
  • 如果ALX为1而ALY为0,它将把子输入转换为输出
  • 如果ALX为1并且ALY也为1,则将输入并输入到输出

以下是我的一些alu模块

module alu (CLK, RST, ALE, ALX , ALY, iDATA, oDATA , flags,aDATA);
input wire CLK, ALE, ALX, ALY,RST;
input wire [3:0] iDATA;
output reg [3:0] oDATA;
output reg [3:0] flags;
output reg [2:0] aDATA;

//declare variables

reg [3:0] nextflags;
wire [3:0] ALU;
wire [3:0] SUM;
wire CIN;
wire claCF,claZF,claNF,claVF;

cla4 test(iDATA,oDATA,CIN,SUM,claCF,claZF,claNF,claVF);
assign CIN = ALX;
assign ALU = ALX ? (ALY ? iDATA & oDATA : SUM) : (ALY ? SUM : iDATA ); //loop 
always @ (posedge CLK, posedge RST) begin
if (RST) begin
oDATA <= 0;
flags <= 0;
end

else if(ALE) begin
oDATA <= ALU;
flags <= nextflags;
end

else begin
oDATA <= oDATA;
flags <= flags;
end

always @ (*) begin
aDATA[2:0] = {ALE,ALX,~CIN};
nextflags[3] = ALX ? ( ALY ? flags[3]: claCF ) : (ALY ? claCF : 0 );
nextflags[2] = (ALU==0);
nextflags[1] = ALU[3];
nextflags[0] = ALX ? ( ALY ? flags[0] : claVF ) : (ALY ? claVF : 0 );
end
endmodule

这是我的输出

 time:                   0 OUTPUT:0000 ADATA:001 C:0 Z:0 N:0 V:0 
 time:                   1 OUTPUT:0000 ADATA:110 C:0 Z:0 N:0 V:0 
 time:                   2 OUTPUT:0001 ADATA:110 C:1 Z:0 N:0 V:0 
 time:                   4 OUTPUT:0000 ADATA:110 C:1 Z:1 N:0 V:0 
 time:                   6 OUTPUT:0001 ADATA:110 C:1 Z:0 N:0 V:0 
 time:                   8 OUTPUT:0000 ADATA:110 C:1 Z:1 N:0 V:0 
 time:                  10 OUTPUT:0001 ADATA:110 C:1 Z:0 N:0 V:0 
 time:                  12 OUTPUT:0000 ADATA:110 C:1 Z:1 N:0 V:0 
 time:                  14 OUTPUT:0001 ADATA:110 C:1 Z:0 N:0 V:0 
 time:                  16 OUTPUT:0000 ADATA:110 C:1 Z:1 N:0 V:0 
 time:                  18 OUTPUT:0001 ADATA:110 C:1 Z:0 N:0 V:0 
 time:                  20 OUTPUT:0000 ADATA:110 C:1 Z:1 N:0 V:0 

2 个答案:

答案 0 :(得分:0)

您将提供完整的代码吗?由于IO命名,很难找到该错误。

您有一个时序电路,因此必须首先等待时钟的上升沿,然后检查控制信号(ALY,ALX)的变化,然后最后将数据信号传播到组合电路(cla4)。因此,必须在always块中实现第四行。

顺便说一句,最好避免在assign语句上使用多个条件,除非您100%确信它是正确的。

在always块中,您可以使用case语句:

   always @ (posedge CLK, posedge RST) begin
if (RST) begin
oDATA <= 0;
flags <= 0;
end

else 
    case({ALX ,ALY}) 
        2'b00 : begin /* */ end
        2'b10 : begin /* */ end
        2'b01 : begin /* */ end
        2'b11 : begin /* */ end



    endcase
   end

答案 1 :(得分:0)

我犯了一个愚蠢的错误,并通过更改进位提前加法器函数

的oDATA和iDATA位置来解决此错误
cla4 test(oDATA,iDATA,CIN,SUM,claCF,claZF,claNF,claVF);

因为在我的提前携带加法器模块中,我将第一个变量声明为需要添加到的变量。

module cla4 (X,Y,M,S,CF,ZF,NF,VF);

assign G = X & (Y ^ {4{CIN}});
assign P = X ^ (Y ^ {4{CIN}});

所以输出将进入循环,因为它基本上会将它与进位本身进行异或。该值只是在xor值与其原始值之间来回变化。