Verilog学习7——case的使用

系列文章目录

Verilog学习1——三目运算符
Verilog学习2——与门(按位与和逻辑与)
Verilog学习3——向量
Verilog学习4——取反与移位运算
Verilog学习5——门电路
Verilog学习6——加法器
Verilog学习7——case的使用


一、case的用法

Verilog中的case语句几乎等同于if-elseif-else的序列,该序列将一个表达式与其他表达式的列表进行比较。它的语法和功能与C语言中的switch语句不同。使用方法如下:

always @(*) 
   begin     // This is a combinational circuit
    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
  1. case语句以case开头,每个“case项”以冒号结尾。不使用“switch”。
  2. 每个case项只能执行一个语句,如果需要执行多个语句,则必须使用begin-end。
  3. 允许重复(和部分重叠)的case项,使用第一个匹配的。C语言不允许重复case项。

例:创建一个6对1多路复用器。当sel介于0和5之间时,选择相应的数据输入,否则输出0。数据输入和输出均为4位宽。

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'd0: out = data0;
            3'd1: out = data1;
            3'd2: out = data2;
            3'd3: out = data3;
            3'd4: out = data4;
            3'd5: out = data5;
            default: out = 0;
        endcase
    end
endmodule

二、casez的用法

为8位输入构建优先级编码器。给定一个8位向量,输出应该报告向量中的第一个(最低有效)高电平位,即1。如果输入向量没有高电平位,则报告零。例如,输入8’d10010000应该输出3’d4,因为位[4]是第一个高电平的位。
若使用case语句,则需要有256个case项。而如果case语句中的某些case项不属于关键位,我们可以将其减少到9个case。这就是casez的作用:在比较中,它将具有值z的位视为不需要比较。
八位优先级编码器:

module top_module (
    input [7:0] in,
    output reg [2:0] pos );
    always@(*)
        begin
            casez(in)
                8'b00000000: pos = 0;
                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
        end
endmodule

三、避免latch的产生

假设您正在构建一个电路来处理键盘上的扫描代码。给定接收到的扫描代码的最后两个字节,您需要指示是否按下了键盘上的一个箭头键。这涉及到一个相当简单的映射,它可以用四个case语句(或者如果elseif)来实现。
在这里插入图片描述
这个电路有一个16位输入和四个输出。在构建此电路时,为了避免产生锁存器,必须在所有可能的条件下为所有输出都分配一个值。仅仅有一个default是不够的。在所有四种情况和默认情况下,必须为四个输出都指定一个值。一个简单的方法是在case语句之前为输出分配一个“默认值”:

module top_module (
    input [15:0] scancode,
    output reg left,
    output reg down,
    output reg right,
    output reg up  ); 
    always @(*)
        begin
            left = 1'b0;
            down = 1'b0;
            right = 1'b0;
            up = 1'b0;
            case(scancode)
                16'he06b: left = 1'b1;
                16'he072: down = 1'b1;
                16'he074: right = 1'b1;
                16'he075: up = 1'b1;      
            endcase
        end
endmodule
序列检测器是一种电路,用于检测输入信号序列是否符合某种特定的模式。在Verilog HDL语言中,可以使用状态机来实现序列检测器。以下是一个简单的序列检测器的Verilog HDL代码示例: ```verilog module sequence_detector( input clk, // 时钟信号 input reset, // 复位信号 input data, // 输入数据信号 output reg match // 匹配信号 ); // 定义状态 typedef enum logic [1:0] { STATE_IDLE, // 空闲状态 STATE_S1, // 状态1 STATE_S2, // 状态2 STATE_S3 // 状态3 } state_t; // 定义状态转移表 parameter [3:0] TRANS_TABLE [0:3] = '{4'b0000, 4'b0001, 4'b0010, 4'b0100}; // 定义当前状态变量和下一个状态变量 reg [1:0] state, next_state; // 初始化状态为IDLE initial begin state = STATE_IDLE; end // 定义状态机逻辑 always @ (posedge clk, posedge reset) begin if (reset) begin state <= STATE_IDLE; end else begin state <= next_state; end end // 定义状态转移逻辑 always @ (*) begin case (state) STATE_IDLE: begin if (data) begin next_state = STATE_S1; end else begin next_state = STATE_IDLE; end end STATE_S1: begin if (!data) begin next_state = STATE_IDLE; end else if (data) begin next_state = STATE_S2; end end STATE_S2: begin if (!data) begin next_state = STATE_IDLE; end else if (data) begin next_state = STATE_S3; end end STATE_S3: begin if (!data) begin next_state = STATE_IDLE; match = 1; end else begin next_state = STATE_S3; end end endcase end endmodule ``` 这个序列检测器可以检测输入数据信号是否符合“1101”这个模式。输入数据信号通过data端口输入,匹配结果通过match端口输出。当输入数据信号符合“1101”这个模式时,match信号会被置为1。如果输入数据信号不符合模式,match信号会保持为0。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值