HDLbits刷题记录(已移至Github)

HDLbits

除工程文件使用vivado外,平时一直是使用 VScode 结合 iverilog 和 GTKwave 来练习,轻量省事。 在此记录下HDLbits网站练习,后边也放些别的练习。

//以下正文//

problem 14

Problem description

Gates4
out_and: output of a 4-input AND gate.
out_or: output of a 4-input OR gate.
out_xor: output of a 4-input XOR gate.

Solution
module top_module ( 
    input [3:0] in,
    output out_and,
    output out_or,
    output out_xor
);
    
    assign out_and = & in;
    assign out_or  = | in;
    assign out_xor = ^ in;
endmodule
  • 逐位逻辑运算符:对于 N 比特输入向量之间的逻辑比较,会在 N 比特上逐位进行,并产生一个 N 比特长的运算结果。
  • 逻辑运算符:任何类型的输入都会被视作布尔值,将布尔值进行逻辑比较后,输出一个 1 比特的结果。

problem 15

Problem description

A Bit of Practice
5-bit input vectors: a, b, c, d, e.
8-bit output vectors: w, x, y, and z.
Vector3.png

Solution
module top_module (
    input [4:0] a, b, c, d, e, f,
    output [7:0] w, x, y, z );//

    assign w = { a, b[4:2] };
    assign x = { b[1:0], c, d[4] };
    assign y = { d[3:0], e[4:1] };
    assign z = { e[0], f, 2'b11 };
endmodule
  • 连接操作符的基本语法使用 { } 将较小的向量括起来,每个 { } 内的向量使用逗号作为间隔。
  • 连接运算符中的向量务必需要标注位宽。
  • 这里是在赋值语句右侧使用位连接符,在左侧使用位连接符的场景也很常见,比如在全加器中使用一句 assign 语句实现结果和进位的赋值。

problem 16

Solution
module top_module( 
    input [7:0] in,
    output reg [7:0] out
);

integer i;
always @(*) begin
    for (i=0; i<8; i=i+1) begin
        out[i] = in[8-i-1];
    end
end
endmodule

problem 17

Solution
module top_module (
    input [7:0] in,
    output [31:0] out );//

    // assign out = { replicate-sign-bit , the-input };
    assign out = {{24{in[7]}}, in};

endmodule

problem 18

Solution
module top_module (
    input a, b, c, d, e,
    output [24:0] out );//

    assign out = ~{ {5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}} } ^ {5{a, b, c, d, e}};

endmodule

//过于基础,不予记录//

problem 23

Problem description

Module shift8.png

Solution
module top_module ( 
    input clk, 
    input [7:0] d, 
    input [1:0] sel, 
    output [7:0] q 
);
    wire  [7:0]  q1, q2, q3;
    my_dff8 dff_1   (clk, d, q1);
    my_dff8 dff_2   (clk, q1, q2);
    my_dff8 dff_3   (clk, q2, q3);

    always @(*) begin
        case (sel)
            0: q = d;
            1: q = q1;
            2: q = q2;
            3: q = q3;
        endcase
    end
endmodule

problem 29

Solution
// 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 @(*) begin
    out_alwaysblock = a & b;
end

endmodule

problem 30

Solution
// 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 @(*) begin
    out_always_comb = a ^ b;
end

always @(posedge clk) begin
    out_always_ff <= a ^ b;
end

endmodule

problem 31

Solution
// synthesis verilog_input_version verilog_2001
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 @(sel_b1 or sel_b2) begin
    if (sel_b1 & sel_b2) begin
        out_always = b;
    end else begin
        out_always = a;
    end
end

endmodule

problem 33

Solution
// synthesis verilog_input_version verilog_2001
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 = 0;
        endcase
    end

endmodule

problem 36

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

problem 37

Solution
module top_module (
    input [7:0] a, b, c, d,
    output [7:0] min
);//

    wire [7:0] intermediate_result1;
    wire [7:0] intermediate_result2;

    // assign intermediate_result1 = compare? true: false;
    assign intermediate_result1 = a<b ? a:b;
    assign intermediate_result2 = c<d ? c:d;
    assign min = intermediate_result1<intermediate_result2 ? intermediate_result1:intermediate_result2;

endmodule

problem 40

Solution
module top_module( 
    input [99:0] in,
    output reg [99:0] out
);
    
integer i;
always @(*) begin
    for (i = 0; i<100; i = i+1) begin
        out[i] = in[99-i];
    end
end

endmodule

problem 41

Solution
module top_module( 
    input [254:0] in,
    output [7:0] out 
);

reg [7:0] cnt;
integer i;
always @(*) begin
    cnt = 0;
    for (i = 0; i < 255; i = i+1) begin
        if (in[i] == 1) begin
            cnt = cnt + 1'b1;
        end else begin
            cnt = cnt;
        end
    end
end

assign out = cnt;

endmodule

problem 42

Solution
module top_module( 
    input [99:0] a, b,
    input cin,
    output [99:0] cout,
    output [99:0] sum
);

reg [99:0]  cout_reg;
reg [99:0]  sum_reg;

integer i;
always @(*) begin
    cout_reg = 0;
    sum_reg  = 0;
    {cout_reg[0], sum_reg[0]} = a[0] + b[0] + cin;
    for (i = 1; i < 100; i = i+1) begin
        {cout_reg[i], sum_reg[i]} = a[i] + b[i] + cout_reg[i-1];
    end
end

assign cout = cout_reg;
assign sum  = sum_reg;

endmodule

Other exercises

test 1
/*
//给定8个数,以及若干二输入比较器。
//要求在单周期内实现8个数的排序,
//并使用最好的比较器个数。
*/
module sort8 #(
    parameter DW = 8
)(
    input       [DW-1:0]    i_d0,
    input       [DW-1:0]    i_d1,
    input       [DW-1:0]    i_d2,
    input       [DW-1:0]    i_d3,
    input       [DW-1:0]    i_d4,
    input       [DW-1:0]    i_d5,
    input       [DW-1:0]    i_d6,
    input       [DW-1:0]    i_d7,

    output reg  [DW-1:0]    o_d0,
    output reg  [DW-1:0]    o_d1,
    output reg  [DW-1:0]    o_d2,
    output reg  [DW-1:0]    o_d3,
    output reg  [DW-1:0]    o_d4,
    output reg  [DW-1:0]    o_d5,
    output reg  [DW-1:0]    o_d6,
    output reg  [DW-1:0]    o_d7
);

function [DW*2-1:0] max;
    input [DW-1:0]  data0;
    input [DW-1:0]  data1;
    begin
        max = data0 <= data1 ? {data1, data0} : {data0, data1};
    end
endfunction

function [DW*4-1:0] max_4;
    input   [DW-1:0] d0;
    input   [DW-1:0] d1;
    input   [DW-1:0] d2;
    input   [DW-1:0] d3;

    reg     [DW-1:0] r0;
    reg     [DW-1:0] r1;
    reg     [DW-1:0] r2;
    reg     [DW-1:0] r3;
    reg     [DW-1:0] r4;
    reg     [DW-1:0] r5;
    reg     [DW-1:0] r6;
    reg     [DW-1:0] r7;
    reg     [DW-1:0] r8;
    reg     [DW-1:0] r9;

    begin
        {r0,r1} = max(d0,d1);
        {r2,r3} = max(d2,d3);
        {r4,r5} = max(r0,r2);
        {r6,r7} = max(r1,r3);
        {r8,r9} = max(r6,r5);
        max_4 = {r4, r8, r9, r7};
    end
endfunction

// reg [DW*4-1:0]  max_4_r;
// always @(*) begin
//     max_4_r = max_4(i_d0, i_d1, i_d2, i_d3);
// end

// assign o_d0 = max_4_r[ 7: 0];
// assign o_d1 = max_4_r[15: 8];
// assign o_d2 = max_4_r[23:16];
// assign o_d3 = max_4_r[31:24];

//8输入比较
reg [DW-1:0] m0, m1, m2, m3, m4, m5, m6, m7, m8, m9;
reg [DW-1:0] m10, m11, m12, m13, m14, m15, m16, m17, m18, m19;

always @(*) begin
    {m0, m1, m2, m3} = max_4 (i_d0, i_d1, i_d2, i_d3);
    {m4, m5, m6, m7} = max_4 (i_d4, i_d5, i_d6, i_d7);
    {m8, m9, m10, m11} = max_4 (m0, m1, m4, m5);
    {m12, m13, m14, m15} = max_4 (m2, m3, m6, m7);
    {m16, m17, m18, m19} = max_4 (m10, m11, m12, m13);

    o_d0 = m15;
    o_d1 = m14;
    o_d2 = m19;
    o_d3 = m18;
    o_d4 = m17;
    o_d5 = m16;
    o_d6 = m9;
    o_d7 = m8;
end

endmodule

module sort8_tst();

reg [8-1:0] i_d0 ;
reg [8-1:0] i_d1 ;
reg [8-1:0] i_d2 ;
reg [8-1:0] i_d3 ;
reg [8-1:0] i_d4 ;
reg [8-1:0] i_d5 ;
reg [8-1:0] i_d6 ;
reg [8-1:0] i_d7 ;
wire [8-1:0]o_d0 ;
wire [8-1:0]o_d1 ;
wire [8-1:0]o_d2 ;
wire [8-1:0]o_d3 ;
wire [8-1:0]o_d4 ;
wire [8-1:0]o_d5 ;
wire [8-1:0]o_d6 ;
wire [8-1:0]o_d7 ;

sort8 U_sort8(
.i_d0(i_d0),
.i_d1(i_d1),
.i_d2(i_d2),
.i_d3(i_d3),
.i_d4(i_d4),
.i_d5(i_d5),
.i_d6(i_d6),
.i_d7(i_d7),
.o_d0(o_d0),
.o_d1(o_d1),
.o_d2(o_d2),
.o_d3(o_d3),
.o_d4(o_d4),
.o_d5(o_d5),
.o_d6(o_d6),
.o_d7(o_d7)
);

initial
begin
i_d0=8'd23;
i_d1=8'd87;
i_d2=8'd3;
i_d3=8'd76;
i_d4=8'd1;
i_d5=8'd2;
i_d6=8'd3;
i_d7=8'd4;
end

endmodule
test 2
module uart_tx(
    //global clock
    input           clk,
    input           rst_n,
    //uart interface
    output reg      uart_tx,
    //user interface
    input   [31:0]  pinlv,
    input           pinlv_value
);

parameter BPS_9600 = 5208;
//count for bps_clk
reg [14:0] cnt_bps_clk;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cnt_bps_clk <= 1'b0;
    end else if (pinlv_value == 0) begin
        cnt_bps_clk <= 1'b0;
    end else if (cnt_bps_clk == BPS_9600 - 1) begin
        cnt_bps_clk <= cnt_bps_clk + 1'b1;
    end
end

reg  [31:0] cnt_bps_stop;
wire        stop_done;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cnt_bps_stop <= 0;
    end else if (state == STOP) begin
        cnt_bps_stop <= 0;
    end else if (cnt_bps_stop > 50_000_00) begin
        cnt_bps_stop <= 0;
    end else
        cnt_bps_stop <= cnt_bps_stop + 1'b1;
end

assign  stop_done = (cnt_bps_stop == 49_000_00) ? 1 : 0;
//clk for bps
reg bps_clk;
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        bps_clk <= 1'b0;
    end else if (cnt_bps_clk == 1) begin
        bps_clk <= 1'b1;
    end else
        bps_clk <= 1'b0;
end
//cnt for bps
reg [14:0] bps_cnt;
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        bps_cnt <= 1'b0;
    end else if (bps_cnt == 10) begin
        bps_cnt <= 0;
    end else if (bps_clk) begin
        bps_cnt <= bps_cnt + 1'b1;
    end else
        bps_cnt <= bps_cnt;
end
//tx state
localparam IDLE = 4'd0;
localparam TX_1 = 4'd1;
localparam TX_2 = 4'd2;
localparam TX_3 = 4'd3;
localparam TX_4 = 4'd4;
localparam STOP = 4'd5;
localparam STOP_1 = 4'd6;
//cnt state
reg [3:0] state;
always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        state <= IDLE;
    else if (state == STOP_1 && stop_done)
        state <= IDLE;
    else if (bps_cnt == 10 && (state != STOP_1))    
        state <= state + 1'b1;
end
//state
always @(posedge clk) begin
    if (bps_clk) begin
        case (state)
            IDLE : //'t' l -- h 
                begin
                    case (bps_cnt)
                        4'd0 : uart_tx <= 0; //begin

                        4'd1 : uart_tx <= 0; //data
                        4'd2 : uart_tx <= 0;
                        4'd3 : uart_tx <= 1;
                        4'd4 : uart_tx <= 0;
                        4'd5 : uart_tx <= 1;
                        4'd6 : uart_tx <= 1;
                        4'd7 : uart_tx <= 1;
                        4'd8 : uart_tx <= 0;

                        4'd9 : uart_tx <= 1; //stop
                        default : uart_tx <= 1;
                    endcase
                end
            TX_1 : //tx_1byte
                begin
                    case (bps_cnt)
                        4'd0 : uart_tx <= 0; //begin

                        4'd1 : uart_tx <= pinlv[24]; //data
                        4'd2 : uart_tx <= pinlv[25];
                        4'd3 : uart_tx <= pinlv[26];
                        4'd4 : uart_tx <= pinlv[27];
                        4'd5 : uart_tx <= pinlv[28];
                        4'd6 : uart_tx <= pinlv[29];
                        4'd7 : uart_tx <= pinlv[30];
                        4'd8 : uart_tx <= pinlv[31];

                        4'd9 : uart_tx <= 1; //stop
                        default : uart_tx <= 1;
                    endcase
                end
            TX_2 : //tx_1byte
                begin
                    case (bps_cnt)
                        4'd0 : uart_tx <= 0; //begin

                        4'd1 : uart_tx <= pinlv[16]; //data
                        4'd2 : uart_tx <= pinlv[17];
                        4'd3 : uart_tx <= pinlv[18];
                        4'd4 : uart_tx <= pinlv[19];
                        4'd5 : uart_tx <= pinlv[20];
                        4'd6 : uart_tx <= pinlv[21];
                        4'd7 : uart_tx <= pinlv[22];
                        4'd8 : uart_tx <= pinlv[23];

                        4'd9 : uart_tx <= 1; //stop
                        default : uart_tx <= 1;
                    endcase
                end
            TX_3 :
                begin
                    case (bps_cnt)
                        4'd0 : uart_tx <= 0; //begin

                        4'd1 : uart_tx <= pinlv[ 8]; //data
                        4'd2 : uart_tx <= pinlv[ 9];
                        4'd3 : uart_tx <= pinlv[10];
                        4'd4 : uart_tx <= pinlv[11];
                        4'd5 : uart_tx <= pinlv[12];
                        4'd6 : uart_tx <= pinlv[13];
                        4'd7 : uart_tx <= pinlv[14];
                        4'd8 : uart_tx <= pinlv[15];

                        4'd9 : uart_tx <= 1; //stop
                        default : uart_tx <= 1;
                    endcase
                end
            TX_4 :
                begin
                    case (bps_cnt)
                        4'd0 : uart_tx <= 0; //begin

                        4'd1 : uart_tx <= pinlv[0]; //data
                        4'd2 : uart_tx <= pinlv[1];
                        4'd3 : uart_tx <= pinlv[2];
                        4'd4 : uart_tx <= pinlv[3];
                        4'd5 : uart_tx <= pinlv[4];
                        4'd6 : uart_tx <= pinlv[5];
                        4'd7 : uart_tx <= pinlv[6];
                        4'd8 : uart_tx <= pinlv[7];

                        4'd9 : uart_tx <= 1; //stop
                        default : uart_tx <= 1;
                    endcase
                end
            STOP :
                begin
                    case (bps_cnt)
                        4'd0 : uart_tx <= 0; //begin

                        4'd1 : uart_tx <= pinlv[0]; //data
                        4'd2 : uart_tx <= pinlv[0];
                        4'd3 : uart_tx <= pinlv[0];
                        4'd4 : uart_tx <= pinlv[1];
                        4'd5 : uart_tx <= pinlv[1];
                        4'd6 : uart_tx <= pinlv[1];
                        4'd7 : uart_tx <= pinlv[1];
                        4'd8 : uart_tx <= pinlv[0];

                        4'd9 : uart_tx <= 1; //stop
                        default : uart_tx <= 1;
                    endcase
                end
            STOP_1 :
                begin
                    uart_tx <= 1;
                end
            default : uart_tx <= 1;
        endcase
    end 
    else
        uart_tx <= uart_tx;
end

endmodule

problem

Solution

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 我可以给你一些代码,可以让你使用Markdown语言记录你的刷题记录:``` # 刷题记录## 今日刷题- 题目 1: - 解答:- 题目 2: - 解答:## 昨日刷题- 题目 1: - 解答:- 题目 2: - 解答: ``` ### 回答2: 生成一个markdown语言的代码刷题记录可以通过以下步骤完成: 1. 创建一个markdown文件,命名为"刷题记录.md",并打开编辑器。 2. 在文件中添加一个标题,例如"刷题记录"。 3. 在下方添加一个表格,表格包含以下列:日期、题目名称、题目难度、代码链接、思路。 4. 为每一道题目添加一行记录,按照日期倒序排列。每行填写相应的信息,包括日期、题目名称、题目难度、代码链接和思路。 示例: | 日期 | 题目名称 | 题目难度 | 代码链接 | 思路 | | -------- | ------------ | ---------- | ----------- | -------- | | 2021/1/1 | 两数之和 | 简单 | [代码链接]() | 思路描述 | | 2021/1/2 | 反转链表 | 中等 | [代码链接]() | 思路描述 | | 2021/1/3 | 接雨水 | 困难 | [代码链接]() | 思路描述 | | ... | ... | ... | ... | ... | 5. 在代码链接处添加相应题目的代码链接,可以使用GitHub或Gist等代码托管平台。 6. 在思路处添加题目解法的思路描述,可以简要概括解法的关键步骤或思想。 完成以上步骤后,保存并关闭markdown文件。这样就生成了一个简单的代码刷题记录,方便查看和整理自己的刷题历程,以及回顾解题思路。 ### 回答3: 生成一个markdown语言的代码刷题记录可以按照以下步骤进行: 1. 首先创建一个markdown文件,可以以`.md`为扩展名,比如`leetcode.md`。 2. 在markdown文件中使用标题,表示题目的名称和难度。比如: ``` # [题目名称](题目链接) - 难度 ``` 3. 接下来,按照以下格式记录每道题目的代码和解题思路: ``` ## 题目描述 题目的具体描述和要求。 ## 解题思路 解题的思路和步骤。 ## 代码实现 使用适当的代码块标记,插入代码。 ```python # Python代码示例 解法代码 ``` ```cpp // C++代码示例 解法代码 ``` ## 复杂度分析 对解法进行时间复杂度和空间复杂度的分析。 ## 总结 对题目和解法进行总结。 ``` 4. 按照上述格式记录完每道题目的代码和解题思路后,保存markdown文件。 5. 在记录新的刷题内容时,可以按照上述格式在文件后面追加新的题目记录。 总结起来,生成一个markdown语言的代码刷题记录,需要创建一个markdown文件,并按照一定的格式记录每道题目的代码和解题思路。这样可以方便地查看每道题目的代码和解法,并进行总结和复习。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值