HDLBits刷题Day8

这篇博客探讨了Verilog编程中的条件语句用法,包括if语句和case语句。通过示例展示了如何构建2对1和6对1多路复用器,以及4位和8位优先级编码器。同时,强调了避免产生锁存器的注意事项,提供了解决方案。此外,还涉及到了一个识别PS/2键盘箭头键的电路设计,利用case语句实现了输入扫描码到输出信号的映射。
摘要由CSDN通过智能技术生成

2.4.3 If statement
问题陈述:

构建一个在a和b之间进行选择的 2 对 1 多路复用器。如果sel_b1和sel_b2都为真,则选择b 。否则,选择. 做同样的事情两次,一次使用分配语句,一次使用过程 if 语句。

请添加图片描述

Verilog代码:

module top_module(
    input a,
    input b,
    input sel_b1,
    input sel_b2,
    output wire out_assign,
    output reg out_always   ); 
    assign out_assign=(sel_b1&&sel_b2)? b:a;
    always @(*)
        begin
            if(sel_b1&&sel_b2)
                begin
                    out_always=b;
                end
            else
                begin
                    out_always=a;
                end
        end
endmodule

2.4.4 If statement latches
问题陈述:

以下代码包含创建闩锁的不正确行为。修复错误,以便您仅在计算机真正过热时关闭计算机,并在您到达目的地或需要加油时停止驾驶。
在这里插入图片描述
always @(*) begin
if (cpu_overheated)
shut_off_computer = 1; end

always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty; end

Verilog代码:

module top_module (
    input      cpu_overheated,
    output reg shut_off_computer,
    input      arrived,
    input      gas_tank_empty,
    output reg keep_driving  ); //

    always @(*) begin
        if (cpu_overheated)
           shut_off_computer = 1;
        else if (~cpu_overheated)
            shut_off_computer=0;
    end

    always @(*) begin
        if (~arrived)
           keep_driving = ~gas_tank_empty;
        else
            keep_driving=0;
    end

endmodule

2.4.5 Case statement
问题陈述:

如果有大量 case,case 语句比 if 语句更方便。因此,在本练习中,创建一个 6 对 1 多路复用器。当sel在 0 到 5 之间时,选择对应的数据输入。否则,输出 0。数据输入和输出均为 4 位宽。

小心推断锁存器

Verilog代码:

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=3'b0;
        endcase            
    end
endmodule

2.4.6 Priority encoder
问题陈述:

构建一个 4 位优先级编码器。对于这个问题,如果没有一个输入位为高(即输入为零),则输出零。请注意,一个 4 位数字有 16 种可能的组合。

Verilog代码:

module top_module (
    input [3:0] in,
    output reg [1:0] pos  );
    always@(*)
        begin
            casez(in)
                4'bzzz1:pos=2'd0;
                4'bzz10:pos=2'd1;
                4'bz100:pos=2'd2;
                4'b1000: pos=2'd3;
                default pos=0;
            endcase
        end
endmodule

2.4.7 Priority encoder with casez
问题陈述:

为 8 位输入构建优先级编码器。给定一个 8 位向量,输出应报告向量中的第一位1。如果输入向量没有高位,则报告零。

Verilog代码:

module top_module (
    input [7:0] in,
    output reg [2:0] pos  );
    always @(*)
        begin 
            casez(in)
                8'bz1:pos=0;
                8'bz10:pos=1;
                8'bz100:pos=2;
                8'bz1000:pos=3;
                8'bz10000:pos=4;
                8'bz100000:pos=5;
                8'bz1000000:pos=6;
                8'b10000000:pos=7;
                default pos=0;
            endcase
        end            
endmodule

2.4.8 Avoiding latches
问题陈述:

假设您正在构建一个电路来处理来自游戏的 PS/2 键盘的扫描码。鉴于收到的扫描码的最后两个字节,您需要指出是否已按下键盘上的箭头键之一。这涉及到一个相当简单的映射,它可以实现为具有四个案例的案例语句(或 if-elseif)。

Scancode [15:0]Arrow key
16’he06bleft arrow
16’he072down arrow
16’he074right arrow
16’he075up arrow
Anything elsenone

您的电路有一个 16 位输入和四个输出。构建识别这四个扫描码并断言正确输出的电路。

Verilog代码:

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

每日总结
一、条件语句
1.3种形式的if语句

  1. if(表达式)语句。例如:
    if(a>b)
    out1=int1;
  2. if(表达式)
    语句1;
    else
    语句2;
    3)if(表达式1)
    语句1;
    else if(表达式2) 语句2;
    else if(表达式3) 语句3;…
    注意:条件语句必须再过程块中使用。所谓的过程块语句是指由initial和always语句引导的执行语句集合。
    二、case语句
    case语句处理多分支的选择。通常用于微处理器的指令译码。
    一般形式如下:
1case(表达式)<case分支>	endcase
2)casez(表达式)<case分支>	endcase//casez用来处理不考虑高阻值z的比较过程
3)casex(表达式)<case分支>   endcase //casex用来处理高阻值z和不定值的比较过程

说明:
1)default项可有可无,一个case语句里只准有一个default项
2)case语句的所有表达式值的位宽必须相等
注意:
为了避免verilog代码出综合后的电路中的生成锁存器,如果用到if语句,最好写上else项;如果用到case语句,最好写上default项。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值