【HDLBits习题 1】Verilog Language(4)Procedures

1. Alwaysblock1(Always blocks (combinational))

对于组合逻辑电路的always块,其敏感信号列表中建议始终为*,以确保不会漏掉所需信号。

module top_module(
    output wire out_assign,
    output reg  out_alwaysblock, 
    input       a, 
    input       b
);
	assign out_assign = a&b;
    
    always @(*) begin 
        out_alwaysblock = a&b;
    end
endmodule

2. Alwaysblock2(Always blocks (clocked))

对于组合逻辑电路的always块,赋值时使用(=);

对于时序逻辑电路的always块,赋值时使用(<=);

module top_module (
    output wire out_assign,
    output reg  out_always_comb,
    output reg  out_always_ff, 
    input       clk,
    input       a,
    input       b
);
	assign out_assign = a^b;
    
    always @(*) begin
        out_always_comb = a^b;
    end
    
    always @(posedge clk) begin
        out_always_ff <= a^b;
    end
endmodule

3. Always if(If statement)

条件判断语句所实现的是数据选择器

module top_module(
    output wire out_assign,
    output reg  out_always, 
    input       a,
    input       b,
    input       sel_b1,
    input       sel_b2
); 
    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

4. Always if2(If statement latches)

在组合逻辑中若要实现数据选择器,则要为每一种情况设置出相应的输出,否则数据选择器会变成锁存器。

module top_module (
    output reg shut_off_computer,
    output reg keep_driving, 
    input      cpu_overheated,
    input      arrived,
    input      gas_tank_empty,
    
);
    always @(*) begin
        if (cpu_overheated) begin
        	shut_off_computer = 1;
        end
        else begin 
            shut_off_computer = 0;
        end
    end

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

5. Always case(Case statement)

case语句类似于if-elseif-else语句

(1)方法1:        

module top_module ( 
    output reg [3:0] out, 
    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
);
    always @(*) begin
        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'h0;
        endcase
    end
endmodule

(2)方法2:

module top_module ( 
    output reg [3:0] out, 
    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
);
    always @(*) begin
        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 = 4'h0;
        endcase
    end
endmodule

6. Always case2(Priority encoder)

(1)方法1:

module top_module (
    output reg [1:0] pos, 
	input      [3:0] in
);
	always @(*) begin
		case (in)
			4'h0: pos = 2'h0;
			4'h1: pos = 2'h0;
			4'h2: pos = 2'h1;
			4'h3: pos = 2'h0;
			4'h4: pos = 2'h2;
			4'h5: pos = 2'h0;
			4'h6: pos = 2'h1;
			4'h7: pos = 2'h0;
			4'h8: pos = 2'h3;
			4'h9: pos = 2'h0;
			4'ha: pos = 2'h1;
			4'hb: pos = 2'h0;
			4'hc: pos = 2'h2;
			4'hd: pos = 2'h0;
			4'he: pos = 2'h1;
			4'hf: pos = 2'h0;
			default: pos = 2'h0;
		endcase
	end
endmodule

(2)方法2:

module top_module (
    output reg [1:0] pos, 
    input      [3:0] in
);
    always @(*) begin
        case (in)
            in[0]: pos = 2'h0; 
            in[1]: pos = 2'h1; 
            in[2]: pos = 2'h2; 
            in[3]: pos = 2'h3; 
            default: pos = 2'h0;
        endcase        
    end    
endmodule

7. Always casez(Priority encoder with casez)

‘z’代表不关心该位的数值。

module top_module (
    output reg [2:0] pos, 
    input 	   [7:0] in
);
	always @(*) begin
        casez (in)
            8'bzzzzzzz1: pos = 3'h0;
            8'bzzzzzz10: pos = 3'h1;
            8'bzzzzz100: pos = 3'h2;
            8'bzzzz1000: pos = 3'h3;
            8'bzzz10000: pos = 3'h4;
            8'bzz100000: pos = 3'h5;
            8'bz1000000: pos = 3'h6;
            8'b10000000: pos = 3'h7;
            default:     pos = 3'h0;
        endcase
    end
endmodule

8. Always nolatches(Avoiding latches)

给output的参数预分配一个默认值,可以省去default语句。

module top_module (
    output reg left,
    output reg down,
    output reg right,
    output reg up, 
    input [15:0] scancode  
); 
    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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值