代码之家  ›  专栏  ›  技术社区  ›  Abraham Lincoln

Verilog中优先级为8到3的编码器(case,casex)

  •  0
  • Abraham Lincoln  · 技术社区  · 7 年前

    真值表为:

              INPUTS            OUTPUTS   
    E | 0 1 2 3 4 5 6 7 ** A2 A1 A0 | GS EO
    ///////////////////////////////////////
    H | X X X X X X X X ** Z  Z  Z  | H  H
    L | H H H H H H H H ** Z  Z  Z  | H  L
    L | X X X X X X X L ** L  L  L  | L  H
    L | X X X X X X L H ** L  L  H  | L  H
    L | X X X X X L H H ** L  H  L  | L  H
    L | X X X X L H H H ** L  H  H  | L  H
    L | X X X L H H H H ** H  L  L  | L  H
    L | X X L H H H H H ** H  L  H  | L  H
    L | X L H H H H H H ** H  H  L  | L  H
    L | L H H H H H H H ** H  H  H  | L  H
    

    以下是我的实现:

    module L348 (E, D0, D1, D2, D3, D4, D5, D6, D7, A0, A1, A2, GS, EO);
    
    input E, D0, D1, D2, D3, D4, D5, D6, D7;
    output A0, A1, A2, GS, EO;
    
    assign D = {D0, D1, D2, D3, D4, D5, D6, D7};
    
    parameter HIGH_IMPEDANCE = 3'bz;
    
    reg [7:0] MASK_1 = 8'b0000_0001;
    reg [7:0] MASK_2 = 8'b0000_0011;
    reg [7:0] MASK_3 = 8'b0000_0111;
    reg [7:0] MASK_4 = 8'b0000_1111;
    reg [7:0] MASK_5 = 8'b0001_1111;
    reg [7:0] MASK_6 = 8'b0011_1111;
    reg [7:0] MASK_7 = 8'b0111_1111;
    reg [7:0] MASK_8 = 8'b1111_1111;
    
    reg [2:0] A;
    reg [1:0] GS_EO;
    reg [7:0] temp;
    
    reg [7:0] mem [7:0];
    
    initial
    begin
    mem[0] = MASK_1;
    mem[1] = MASK_2;
    mem[2] = MASK_3;
    mem[3] = MASK_4;
    mem[4] = MASK_5;
    mem[5] = MASK_6;
    mem[6] = MASK_7;
    mem[7] = MASK_8;
    temp = 8'bxxxx_xxxx;
    end
    
    assign {A2, A1, A0} = A;
    assign {GS, EO} = GS_EO;
    
    integer i;
    
    always @(*)
    begin
    for (i = 7; i > 0; i = i - 1)
        if (mem[i] & D == mem[i])
            begin
            temp = mem[i];
            i = -1;
            end
    if (E)
        begin
        A = HIGH_IMPEDANCE;
        GS_EO = 2'b11;
        end
    else
        begin
            if (temp == 8'b1111_1111)
                begin
                A = HIGH_IMPEDANCE;
                GS_EO = 2'b10;
                end
            else
                begin
    
                GS_EO = 2'b01;
                case (temp)
                    8'b0000_0001: A = 3'b001;
                    8'b0000_0011: A = 3'b010;
                    8'b0000_0111: A = 3'b011;
                    8'b0000_1111: A = 3'b100;
                    8'b0001_1111: A = 3'b101;
                    8'b0011_1111: A = 3'b110;
                    8'b0111_1111: A = 3'b111;
                endcase
    
                end
        end
    end
    endmodule 
    

    它无法实现始终处于X状态的信号A2-A0的切换(E=H时除外)。我尝试了许多解决方案,但感觉模拟器无法管理“case”块(我也尝试了“casex”块)。某处有个bug,但我想不出来。有人有想法吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Brian Magnuson    7 年前

    你有很多事情要做,但你最直接的问题可能是。

    assign D = {D0, D1, D2, D3, D4, D5, D6, D7};
    

    这个隐式定义的导线只有1位宽,因此高7b将被丢弃。Verilog不是很有趣吗?

    还有其他逻辑问题,但使用case语句进行优先级编码器的最简单方法如下:

    casez (in)
      4'b???1 : out = 0;
      4'b??10 : out = 1;
      4'b?100 : out = 2;
      4'b1000 : out = 3;
      default : out = 0; //no match
    endcase
    

    casez 允许您输入 ?

    break 而不是直接修改循环变量。