使用级联2位比较器实现2n位比较器

时间:2016-10-16 14:45:16

标签: logic verilog digital-logic

到目前为止,我有一个2位比较器的代码。

module twobitcomparator(xgtyin,xety,xltyin,x1,x0,y1,y0,xgty,xety,xlty);
//I/O
output xgty, xety, xlty; //xgty - x>y, xlty - x<y, xety - x=y
input x1, x0, y1, y0, xgtyin, xetyin, xltyin;

//specify circuit behavior
assign r = (xgyin);
assign s = (xlyin);
assign t = (xetyin);//not sure if I need an xetyin

assign a = (x1&~y1);
assign b = (x1&x0&~y0);
assign c = (x0&~y1&~y0);
assign xgty = (a|b|c|r);//X>Y

assign d = (~x0&~y0);
assign e = (x0&y0);
assign f = (x1&y1);
assign g = (~x1&~y1);
assign xety = ((d|e)&(f|g));//X=Y

assign h = (~x1&~x0&y0);
assign i = (~x1&y1);
assign j = (~x0&y1&y0);
assign xlty = (h|i|j|s);//X<Y

endmodule

这看起来不错吗?我为它编写了一个测试平台并查看了波形,输出对输入是正确的,但我不确定它是否是最有效的方法。

对于级联,我知道最高位比较器的结果(如果是不等式)只需要通过其余的比较器向下发送,这将是最终结果。如果它们相等,那么我只需要找到存在不等式的最高位比较器,并且需要像我提到的那样级联。

我坚持让他们级联,我对Verilog很新,我不知道如何将每个比较器的结果送到下一个比较器。这是我的尝试。

module ncompare#( parameter n = 2)(input [2*n-1:0] xgyin, xlyin,
input [2*n-1:0] x1, x0, y1, y0,
output [2*n-1:0] xgy, xey, xly,
output xqyout);
wire xqyin;
assign xqyin = 1'b0;

twobitcomparator s1(.xgyin(xgyin[xqyin]), .xlyin(xlyin[xqyin]),
.x1(x1[2*n-1]), .x0(x0[2*n-2]), .y1(y1[2*n-1]), .y0(y0[2*n-2]),
.xgy(xgy[ripple0]), .xey(xey[ripple1]), .xly(xly[ripple2]));

twobitcomparator s0(.xgyin(xgyin[ripple0]), .xlyin(xlyin[ripple2]),
.x1(x1[1]), .x0(x0[0]), .y1(y1[1]), .y0(y0[0]),
.xgy(xgy[ripple3]), .xey(xey[ripple4]), .xly(xly[ripple5]));

endmodule

我想我需要使用一个生成语句,因为我需要让它适用于任何参数n但我不知道如何使用生成因为我所看到的所有示例只有一个输出而我有三个(这也是下一个比较器的输入!Agh!)

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

2位比较器模块可以重写为

module twobitcomparator(xgtyin,xltyin,x,y,xgty,xlty,xety);

  output xgty, xety, xlty;          
  input  xgtyin, xltyin;
  input [1:0] x,y; 

  assign xgty = xgtyin | (~xltyin & ((x[1] > y[1]) | ((x[1] == y[1]) & (x[0] > y[0]))));
  assign xlty = xltyin | (~xgtyin & ((x[1] < y[1]) | ((x[1] == y[1]) & (x[0] < y[0]))));

  assign xety = ~(xlty | xgty);

endmodule

我将两位输入视为总线而不是将它们视为单独的位(Verilog允许您这样做)。我已经删除了代码中存在的众多中间结果。这使代码更容易理解,因为您不必跟踪所有这些临时连线。

然后我在EDA Playground上使用Icarus Verilog模拟了这个模块。链接在这里 https://www.edaplayground.com/x/5KRL

使用这些两比特比较器的四位比较器可以写成如下。

module fourbitcomparator(xgtyin,xltyin,x,y,xgty,xlty,xety);
  output xgty, xety, xlty;          
  input  xgtyin, xltyin;
  input [3:0] x,y; 

  wire xgty_1,xlty_1,xety_1;

  twobitcomparator u_1 (
    .xgtyin(xgtyin),
    .xltyin(xltyin),
    .x(x[3:2]),
    .y(y[3:2]),
    .xgty(xgty_1),
    .xlty(xlty_1),
    .xety(xety_1)
  );

  twobitcomparator u_0 (
    .xgtyin(xgty_1),
    .xltyin(xlty_1),
    .x(x[1:0]),
    .y(y[1:0]),
    .xgty(xgty),
    .xlty(xlty),
    .xety(xety)
  );

endmodule

最后使用两个比特的2n比特比较器,可以推广如下

module twoN_bitcomparator #(
  parameter N = 2
)(
  input xgtyin,
  input xltyin,
  input [(2*N-1):0]x,
  input [(2*N-1):0]y,
  output xgty,
  output xlty,
  output xety
);

  wire [N:0] xgty_w,xlty_w,xety_w;

  assign xgty_w[N] = xgtyin;
  assign xlty_w[N] = xltyin;

  generate
    genvar i;
    for (i=0;i<=(N-1);i=i+1)
      begin:TWOBITGEN
        twobitcomparator u_1 (
          .xgtyin(xgty_w[i+1]),
          .xltyin(xlty_w[i+1]),
          .x(x[(2*i+1) : (2*i)]),
          .y(y[(2*i+1) : (2*i)]),
          .xgty(xgty_w[i]),
          .xlty(xlty_w[i]),
          .xety(xety_w[i])
        );
      end
  endgenerate

  assign xgty = xgty_w[0];
  assign xlty = xlty_w[0];
  assign xety = xety_w[0];

endmodule

此广义模块的模拟也可在https://www.edaplayground.com/x/2fbr的EDA游乐场上获得 小型测试平台的波形也可在https://www.edaplayground.com/w/x/27X

处获得