HDLBits学习笔记(29~36)

HDLBits学习笔记(29~36)

学习阶段:有问题发873727286@qq.com大家一起讨论。

题目29 Alwaysblock1

题目大意:同时用assign和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

题目30 Alwaysblock2

题目大意:使用三种方式实现异或门,分别是assign,组合的always,还要带时钟的always模块。

题目分析:用三种方法实现异或门。

答案:

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

题目31 Always if

题目大意:构建一个2选1数据选择器,如果sel_b1和sel_b2都为真,输出b。
否则输出a。分别用连续赋值语句,和过程赋值语句分别实现。

题目分析:连续赋值语句可以使用三目运算。过程赋值语句用if来实现。

答案:

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

题目32 Always if2

题目大意:以下代码包含创建latch的错误行为。改正这些错误,这样你只有在电脑过热时才会关闭电脑,如果你到达目的地或需要加油,就停止开车。

题目分析:由于条件列举不完全而造成的latch,通过补全if的所有条件来去除。

答案:

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 = 1'b0;
    end

endmodule

题目33 Always case

题目大意:创建一个6选1多路选择器。当sel在0和5之间时,选择相应的数据输出。否则输出0。数据输入和输出均为4位宽。

题目分析:使用case语句,列举所有条件,避免产生latch。

答案:

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

题目34 Always case2

题目大意:优先级编码器是一种组合电路,当给定输入位向量时,输出向量中第一个1位的位置。构建一个4位优先级编码器。

题目分析:case穷举。

答案:

module top_module (
    input [3:0] in,
    output reg [1:0] pos  );
    always@(*)begin
        case(in)
            4'b0000: pos <= 2'b00;
            4'b0001: pos <= 2'b00;
            4'b0010: pos <= 2'b01;
            4'b0011: pos <= 2'b00;
            4'b0100: pos <= 2'b10;
            4'b0101: pos <= 2'b00;
            4'b0110: pos <= 2'b01;
            4'b0111: pos <= 2'b00;
            4'b1000: pos <= 2'b11;
            4'b1001: pos <= 2'b00;
            4'b1010: pos <= 2'b01;
            4'b1011: pos <= 2'b00;
            4'b1100: pos <= 2'b10;
            4'b1101: pos <= 2'b00;
            4'b1110: pos <= 2'b01;
            4'b1111: pos <= 2'b00;
        endcase
    end
endmodule

题目35 Always casez

题目大意:使用casez,来减少case中的条目的数量,使用z来代替输入量中不关心的位置。构建一个8位优先级编码器。

题目分析:使用casez穷举。

答案:

module top_module (
    input [7:0] in,
    output reg [2:0] pos  );
	always @(*) begin
        casez(in[7:0])
            8'bzzzz_zzz1: pos[2:0] = 3'd0;   
        	8'bzzzz_zz1z: pos[2:0] = 3'd1;
            8'bzzzz_z1zz: pos[2:0] = 3'd2;
            8'bzzzz_1zzz: pos[2:0] = 3'd3;
            8'bzzz1_zzzz: pos[2:0] = 3'd4;
            8'bzz1z_zzzz: pos[2:0] = 3'd5;
            8'bz1zz_zzzz: pos[2:0] = 3'd6;
            8'b1zzz_zzzz: pos[2:0] = 3'd7;
    	endcase
	end
endmodule

题目36 Always nolatches

题目大意:电路有一个16位输入和四个输出。构建识别这四个扫描码并确认正确输出的电路。

题目分析:按所给的对应关系输出电路。
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'he072)
        	down  <= 1'b1;
        else if( scancode == 16'he074)
        	right <= 1'b1;
        else if( scancode == 16'he075)
        	up    <= 1'b1;
    end
endmodule
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值