HDLBits(7)9.19

2 Verilog语言

2.4 程序

2.4.5 Always case

当可能的情况较多时,适合使用 case 语句而非 if-else 语句

case 语句以 case 开头,每个 case 项以冒号结束

case 项后的执行语句可以是单条,也可以是多条,但多条需要用 begin-end 进行说明

case项允许重复和部分重叠,执行程序匹配到的第一个

当 case 项均不符合,则执行 default 项

always @(*) begin     
    case (in)
      1'b1: begin 
               out = 1'b1;  // begin-end if >1 statement
            end
      1'b0:    out = 1'b0;
      default: out = 1'bx;
    endcase
end
module top_module ( 
    input [2:0] sel, 
    input [3:0] data0,
    input [3:0] data1,
    input [3:0] data2,
    input [3:0] data3,
    input [3:0] data4,
    input [3:0] data5,
    output reg [3:0] out   );//

    always@(*) begin  // This is a combinational circuit
        case(sel)
            3'b000: out = data0;
            3'b001: out = data1;
            3'b010: out = data2;
            3'b011: out = data3;
            3'b100: out = data4;
            3'b101: out = data5;
        default: out = 4'b0000;
        endcase
    end
endmodule

2.4.6 优先编码器(Priority encoder)

优先编码器是组合电路,当给定输入时,输出输入向量中的右边第一个1的位置。例如,输入8'b10010000的,则优先编码器将输出3'd4,因为位[4]是从右数第一个1

构建一个4位优先编码器。如果没有输入均为零,则输出零

//方法1,将每种可能的数字分别作为case
module top_module (
    input [3:0] in,
    output reg [1:0] pos);

always@(*)
    case(in)
    4'b0000: pos = 2'b00;
    4'b0001: pos = 2'b00;
    4'b0010: pos = 2'b01;
    4'b0011: pos = 2'b00;
    4'b0100: pos = 2'b10;
    4'b0101: pos = 2'b00;
    4'b0110: pos = 2'b01;
    4'b0111: pos = 2'b00;
    4'b1000: pos = 2'b11;
    4'b1001: pos = 2'b00;
    4'b1010: pos = 2'b01;
    4'b1011: pos = 2'b00;
    4'b1100: pos = 2'b10;
    4'b1101: pos = 2'b00;
    4'b1110: pos = 2'b01;
    4'b1111: pos = 2'b00;
    default: pos = 2'b00;
    endcase

endmodule
//由于case项若有多项为真,按照顺序执行匹配到的第一个,所以可以只针对每个位是否为1
module top_module (
    input [3:0] in,
    output reg [1:0] pos  );
    always@(*)begin
        case(1)
            in[0]:pos=2'd0;
            in[1]:pos=2'd1;
            in[2]:pos=2'd2;
            in[3]:pos=2'd3;
            default:pos=2'd0;
        endcase    
    end
endmodule

2.4.7 Always casez

casez:在比较中将具有z的位是为无关项,例如:无论是 10 还是 11 都会匹配到 1z 项

构建一个8输入的优先编码器

module top_module (
    input [7:0] in,
    output reg [2:0] pos);

always @(*)
    casez (in)
        8'bzzzzzzz1: pos = 0;
        8'bzzzzzz1z: pos = 1;
        8'bzzzzz1zz: pos = 2;
        8'bzzzz1zzz: pos = 3;
        8'bzzz1zzzz: pos = 4;
        8'bzz1zzzzz: pos = 5;
        8'bz1zzzzzz: pos = 6;
        8'b1zzzzzzz: pos = 7;
        default: pos = 0;
    endcase

endmodule

2.4.8 Always nolatches

可以通过在always和case之间设置默认值来避免锁存器的生成并减少代码量

module top_module (
    input [15:0] scancode,
    output reg left,
    output reg down,
    output reg right,
    output reg up  ); 
    always @(*) begin
        up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
        case (scancode)
            16'he06b: left = 1;
            16'he072: down = 1;
            16'he074: right = 1;
            16'he075: up = 1;
        endcase
    end
endmodule

 

posted @ 2022-09-19 16:40  LhTian21  阅读(47)  评论(0)    收藏  举报