HDLBits练习(五)Verilog Language_Procedures

Alwaysblock1

要求:使用 assign 语句和 always 块构建 AND 门。

注意:always赋值的左侧必须要是变量如:reg。

module top_module(
    input a, 
    input b,
    output wire out_assign,
    output reg out_alwaysblock
);

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

Alwaysblock2

要求:用下图所示的三种方式实现XOR门。

注意:时序逻辑产生的结果会延迟一个周期。

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) & (~a | ~b);
always@(*)
    out_always_comb = (a | b) & (~a | ~b);
always@(posedge clk)
    out_always_ff = (a | b) & (~a | ~b);

endmodule

Always if

分别使用 if 语句和条件运算符实现下图所示的多路选择器。

 条件运算符  ?: (?前面为条件判断式,结果为真时执行 : 前的语句,为假执行后面的语句)

module top_module(
    input a,
    input b,
    input sel_b1,
    input sel_b2,
    output wire out_assign,
    output reg out_always   ); 

always@(*)
    begin
        if({sel_b1,sel_b2} == 2'b00)
            out_always = a;
        else if({sel_b1,sel_b2} == 2'b01)
            out_always = a;
        else if({sel_b1,sel_b2} == 2'b10)
            out_always = a;
        else
            out_always = b;
    end

assign out_assign = (sel_b1 & sel_b2)? b : a;

endmodule

Always if2

要求:仅在计算机过热时关闭计算机,即cpu_overheted为1时,shut_off_computer为1;当到达目的地或需要加油时,停止驾驶,即arrived或gas_tank_empty为1时,keep_driving为0.

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 | gas_tank_empty)
           keep_driving = 0;
        else
           keep_driving = 1;
    end

endmodule

Always case

要求:使用case语句实现6选1数据选择器,选择信号sel在0到5之间时,选择对应的数据,否则输出0.

如果情况有很多种,使用case语句要比if语句更简便。

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

Always case2

要求:实现一个4位优先编码器,给定一个输入,输出该向量中第一个1的位置,如给定输入8'b1001_0000的 8 位优先级编码器将输出3'd4,因为 bit[4] 是第一个高位。如果输入为0,则输出0.

这里可以将所有case全部列举出来,也可以使用casex语句,对于不关心的高位使用x代替,这里的default是多余的,因为4位输入的所有情况都已列举出来了,如果在没有列举出所有case的场合,不要忘记default。

module top_module (
    input [3:0] in,
    output reg [1:0] pos  );

/* always@(*)
    begin
        case(in)
            4'b0001 : pos = 2'd0;
            4'b0011 : pos = 2'd0;
            4'b0101 : pos = 2'd0;
            4'b0111 : pos = 2'd0;
            4'b1001 : pos = 2'd0;
            4'b1011 : pos = 2'd0;
            4'b1101 : pos = 2'd0;
            4'b1111 : pos = 2'd0;
            4'b0010 : pos = 2'd1;
            4'b0110 : pos = 2'd1;
            4'b1010 : pos = 2'd1;
            4'b1110 : pos = 2'd1;
            4'b0100 : pos = 2'd2;
            4'b1100 : pos = 2'd2;
            4'b1000 : pos = 2'd3;
            default : pos = 2'd0;
        endcase
    end */
    
always @(*) 
    begin
        casex (in)
            4'bxxx1: pos = 2'd0;  
            4'bxx10: pos = 2'd1;
            4'bx100: pos = 2'd2;
            4'b1000: pos = 2'd3;
            default: pos = 2'd0;
        endcase
    end
    
endmodule

Always casez

要求:用casez语句实现8位编码器。

casez语句和casex语句的用法差不多。

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

always @(*) 
    begin
        casez (in[7:0])
            8'bzzzz_zzz1: pos = 3'd0;  
            8'bzzzz_zz10: pos = 3'd1;
            8'bzzzz_z100: pos = 3'd2;
            8'bzzzz_1000: pos = 3'd3;
            8'bzzz1_0000: pos = 3'd4;  
            8'bzz10_0000: pos = 3'd5;
            8'bz100_0000: pos = 3'd6;
            8'b1000_0000: pos = 3'd7;
            default: pos = 3'd0;
        endcase
    end

endmodule 

Always nolatches

要求:实现如下的按键功能,注意避免产生latch。

注意:if...else语句中,条件没有列举完全且没有else,可能产生latch,case语句中没有列举完全且没有default,也可能产生latch。

这里先给四个按键都分配了0,只有当case满足,按键的赋值才会被覆盖,所以这里可以不需要加上default。

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'b1;
            16'he072 : down <= 1'b1;
            16'he074 : right <= 1'b1;
            16'he075 : up <= 1'b1;
        endcase
    end

endmodule

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值