Verilog always语句练习题

Verilog always语句练习题
本文章为练习Verilog语言,做个笔记,方便之后复习查阅,如有错误,欢迎斧正。
题目1:
Build an AND gate using both an assign statement and a combinational always block. (Since assign statements and combinational always blocks function identically, there is no way to enforce that you’re using both methods. But you’re here for practice, right?..)

在这里插入图片描述
我的解答:

// synthesis verilog_input_version verilog_2001
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

题目2:
Build an XOR gate three ways, using an assign statement, a combinational always block, and a clocked always block. Note that the clocked always block produces a different circuit from the other two: There is a flip-flop so the output is delayed.
在这里插入图片描述

我的解答:

// synthesis verilog_input_version verilog_2001
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 @(*)
        out_always_comb = a ^ b;
    
    always @(posedge clk)
        out_always_ff <= a ^ b;

endmodule

题目3:
Build a 2-to-1 mux that chooses between a and b. Choose b if both sel_b1 and sel_b2 are true. Otherwise, choose a. Do the same twice, once using assign statements and once using a procedural if statement.
在这里插入图片描述
我的解答:

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 == 1'b1) && (sel_b2 == 1'b1))
            	out_always <= b;
       		else
            	out_always <= a;
        end

endmodule

题目4:
The following code contains incorrect behaviour that creates a latch. Fix the bugs so that you will shut off the computer only if it’s really overheated, and stop driving if you’ve arrived at your destination or you need to refuel.
在这里插入图片描述

在这里插入图片描述
我的修正代码:

// synthesis verilog_input_version verilog_2001
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;
    end

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

endmodule

题目5:
Case statements are more convenient than if statements if there are a large number of cases. So, in this exercise, create a 6-to-1 multiplexer. When sel is between 0 and 5, choose the corresponding data input. Otherwise, output 0. The data inputs and outputs are all 4 bits wide.

我的解答:

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

题目6:
A priority encoder is a combinational circuit that, when given an input bit vector, outputs the position of the first 1 bit in the vector. For example, a 8-bit priority encoder given the input 8’b10010000 would output 3’d4, because bit[4] is first bit that is high.

Build a 4-bit priority encoder. For this problem, if none of the input bits are high (i.e., input is zero), output zero. Note that a 4-bit number has 16 possible combinations.

思考:四位数字有十六个组合,从第0位开始算。

我的解答:

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

    always@(*)
        begin
     	   case(in)
    			4'h2: pos = 2'd1;
      		    4'h4: pos = 2'd2;
           	    4'h6: pos = 2'd1;
            	4'h8: pos = 2'd3;
            	4'ha: pos = 2'd1;
            	4'hc: pos = 2'd2;
            	4'he: pos = 2'd1;
            default: pos = 2'd0;
        endcase
        end
    
endmodule

官方solution:

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

	always @(*) begin			// Combinational always block
		case (in)
			4'h0: pos = 2'h0;	// I like hexadecimal because it saves typing.
			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'b0;	// Default case is not strictly necessary because all 16 combinations are covered.
		endcase
	end
	
	// There is an easier way to code this. See the next problem (always_casez).
	
endmodule

题目7:
A case statement behaves as though each item is checked sequentially (in reality, it does something more like generating a giant truth table then making gates). Notice how there are certain inputs (e.g., 4’b1111) that will match more than one case item. The first match is chosen (so 4’b1111 matches the first item, out = 0, but not any of the later ones).

There is also a similar casex that treats both x and z as don’t-care. I don’t see much purpose to using it over casez.
The digit ? is a synonym for z. so 2’bz0 is the same as 2’b?0

我的解答:

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

    always @(*) begin
        casez(in)
            8'bzzzz_zzz1: pos = 3'd0;
            8'bzzzz_zz1z: pos = 3'd1;
            8'bzzzz_z1zz: pos = 3'd2;
            8'bzzzz_1zzz: pos = 3'd3;
            8'bzzz1_zzzz: pos = 3'd4;
            8'bzz1z_zzzz: pos = 3'd5;
            8'bz1zz_zzzz: pos = 3'd6;
            8'b1zzz_zzzz: pos = 3'd7;
            default: pos = 3'd0;
        endcase
    end
    
endmodule

题目8:
Suppose you’re building a circuit to process scancodes from a PS/2 keyboard for a game. Given the last two bytes of scancodes received, you need to indicate whether one of the arrow keys on the keyboard have been pressed. This involves a fairly simple mapping, which can be implemented as a case statement (or if-elseif) with four cases.

Scancode [15:0] Arrow key
16’he06b left arrow
16’he072 down arrow
16’he074 right arrow
16’he075 up arrow
Anything else none

我的解答:

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;
        	if(scancode == 16'he06b)
            	left <= 1'b1;
        	else if(scancode == 16'he074)
            	right <= 1'b1;
        	else if(scancode == 16'he072)
            	down <= 1'b1;
        	else if(scancode == 16'he075)
            	up <= 1'b1;
        	else
            	begin
                	up <= 1'b0; 
                	down <= 1'b0; 
                	left <= 1'b0; 
                	right <= 1'b0;
            	end
    	end

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值