HDLbits刷题总结

HDLbits一刷还愿,记录一些有价值的内容。

一、例化数组(举例说明)

  • 对于模块:
module add1(
input a,
input b,
output out
);
	assign out = a + b;
endmodule
  • 除使用generate/endgenerate+for循环方式对重复例化模块进行赋值操作外:
module top(
input [1:0]a,
input [1:0]b,
output [1:0]out
);
genvar i;
generate
	for(i = 0;i <= 1;i = i + 1)begin:uut1
		add1 uut2(.a(a[i]),.b(b[i]),.out(out[i]));
		//add1 uut2(a[i],b[i],out[i]);//必须按照模块端口定义顺序连接
	end
endgenerate
endmodule
  • 还可以使用例化数组的方法:
module top(
input [1:0]a,
input [1:0]b,
output [1:0]out
);
	add1 uut[1:0](.a(a),.b(b),.out(out));
endmodule

其中uut[0]代表第一个例化,对应连接a[0]、b[0]、out[0],依次类推。

二、casez(举例说明)

  • casez的匹配是从上向下匹配的,不关心的位可以设置为z以减少代码量(下面代码功能和多级if/else类似)。
module top_module (
    input [7:0] in,
    output reg [2:0] pos );
    always @(*)begin
        casez(in)
           8'bzzzzzzz1: pos <= 3'd0;
           8'bzzzzzz10: pos <= 3'd1;
           8'bzzzzz100: pos <= 3'd2;
           8'bzzzz1000: pos <= 3'd3;
           8'bzzz10000: pos <= 3'd4;
           8'bzz100000: pos <= 3'd5;
           8'bz1000000: pos <= 3'd6;
           8'b10000000: pos <= 3'd7;
            default:pos <= 'x;//不定态
        endcase
    end
endmodule

三、initial语句

在FPGA中给reg赋初值可以综合(编译器预处理),ASIC设计则不可综合。

四、上升下降双边沿触发器

  • 使用两个触发器实现
module top_module(
	input clk,
	input d,
	output q);
	
	reg p, n;
	
	// A positive-edge triggered flip-flop
    always @(posedge clk)
        p <= d ^ n;
        
    // A negative-edge triggered flip-flop
    always @(negedge clk)
        n <= d ^ p;

    assign q = p ^ n;
endmodule

五、拼接符: {}(举例说明)

{{4{a[0]}},a[3:1]}
//以上表示a[0]重复4次后组成高4位,和a[3:1]所示的低3位组成7bit数据

注意上文大括号的使用位置,重复次数’4‘内外层都需要添加。

六、独热码编码的状态机

使用独热码编码的状态机,状态转移可以对状态对应的bit位分别独立赋值,赋值使用的状态也使用对应bit位代表,对输出赋值类似。

  • 下例Fsm3onehot展示了在状态使用独热编码时对应的状态转移和输出表示:
    在这里插入图片描述
module top_module(
    input in,
    input [3:0] state,
    output [3:0] next_state,
    output out); //

    parameter A=0, B=1, C=2, D=3;

    // State transition logic: Derive an equation for each state flip-flop.
    assign next_state[A] = (state[0] & (~in)) | (state[2] & (~in));
    assign next_state[B] = (state[0] & in) | (state[1] & in) | (state[3] & in);
    assign next_state[C] = (state[1] & (~in)) | (state[3] & (~in));
    assign next_state[D] = (state[2] & in);

    // Output logic: 
    assign out = state[3];

endmodule

七、Conveylife

  • 作为HDLbits有难度的题目之一,这里给出实现方法。
    在这里插入图片描述
module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q ); 
    //这里自下而上,从右到左排列data内的数据(从低位开始排列)
    wire [255:0]right,left,up,down,left_up,right_up,left_down,right_down;
    //right表示相对于原来数据右侧的数据组成的新数据阵列以下类似。
assign    right = {q[254-:15],q[255],q[238-:15],q[239],q[222-:15],q[223],q[206-:15],q[207],
             q[190-:15],q[191],q[174-:15],q[175],q[158-:15],q[159],q[142-:15],q[143],
             q[126-:15],q[127],q[110-:15],q[111],q[94-:15],q[95], q[78-:15],q[79],
             q[62-:15],q[63], q[46-:15], q[47], q[30-:15],q[31], q[14-:15],q[15]};
    
assign    left  = {q[240],q[255-:15],q[224],q[239-:15],q[208],q[223-:15],q[192],q[207-:15],
             q[176],q[191-:15],q[160],q[175-:15],q[144],q[159-:15],q[128],q[143-:15],
             q[112],q[127-:15],q[96], q[111-:15],q[80], q[95-:15],q[64], q[79-:15] ,
             q[48], q[63-:15],q[32], q[47-:15], q[16], q[31-:15],q[0],  q[15-:15]};
    
assign    up    = {q[15:0], q[255:16]};
assign    down  = {q[239:0],q[255:240]};
    
assign    left_up  = {left[15:0],  left[255:16]};
assign    right_up = {right[15:0], right[255:16]};
    
assign    left_down = {left[239:0],left[255:240]};
assign    right_down= {right[239:0],right[255:240]};

    //数据相加和判决
    wire [3:0]sum;
    wire [255:0]q_next;
    integer i;
    always @(*)begin
        for(i=0;i<=255;i=i+1)begin
            sum  = right[i] + left[i] + up[i] + down[i] + left_up[i] + right_up[i] + left_down[i] + right_down[i];
            q_next[i] = (sum == 4'd2) ? (q[i]) : ( (sum == 4'd3) ? (1'b1) : (1'b0) );
        end
    end
    
    always @(posedge clk)begin
        if(load)
            q <= data;
        else begin
            q <= q_next;
        end
    end
endmodule

微信公众号:通信随笔XIDIAN

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xidian_hxc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值