Verilog:HDLBits刷题-条件语句

前言

这是我第二次刷HDLBits的题,第一次是刚接触FPGA时,为了快速入门Verilog,第一次刷题跟着B站视频刷的,但是现在发现没有很大的用处,个人感觉还是有一点Verilog基础后,再来刷HDLBits会好一点,虽然很多人说这上面的题都很简单,但是还是值得刷一遍,里面几乎涵盖了Verilog的所有常用语法,并且还可以尝试用不同方法解同一道题。

代码

以下是我写的每道题的代码和思路


Procedure

注意:

  1. case、if-else语句要避免产生锁存器
// 使用always(*)组合逻辑
module top_module(
    input a, 
    input b,
    output wire out_assign,
    output reg out_alwaysblock
);

    assign out_assign = a & b ;
    always @(*) begin
    out_alwaysblock = a & b;
end

endmodule

// 寄存器、always(clk)时序逻辑、异或
module top_module(
    input clk,
    input a,
    input b,
    output wire out_assign,
    output reg out_always_comb,
    output reg out_always_ff   );

    assign out_assign = a ^ b ;
    always @(*) begin
    out_always_comb = a ^ b;
end
    always @(posedge clk) begin
        out_always_ff <= a ^ b ;
    end

endmodule

// 条件判断
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==1'b1)& (sel_b2==1'b1))?b:a;
    always @(*) begin
        if((sel_b1==1'b1)& (sel_b2==1'b1))
            out_always = b;
        else
            out_always = a;
    end

endmodule

// =======================  4  =========================
// 如何避免产生锁存器:if-else写完

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
           shut_off_computer = 0;
    end

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

endmodule


// case语句,注意位宽
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


// 不要忘记写default
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


// casez
module top_module (
    input [7:0] in,
    output reg [2:0] pos  );
    always @(*) begin
        casez(in)
        8'bzzzzzzz1:pos = 3'd0;
        8'bzzzzzz1z:pos = 3'd1;
        8'bzzzzz1zz:pos = 3'd2;
        8'bzzzz1zzz:pos = 3'd3;
        8'bzzz1zzzz:pos = 3'd4;
        8'bzz1zzzzz:pos = 3'd5;
        8'bz1zzzzzz:pos = 3'd6;
        8'b1zzzzzzz:pos = 3'd7;
        default:pos = 3'd0;
    endcase
    end

endmodule

// 为了避免产生锁存器,在使用case语句前,先给输出赋初值,这样就不用在case语句中使用default
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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值