HDLBits 错题

本文详细探讨了HDLBits中的常见错题,包括串并转换、时钟无毛刺切换、信号比特位选择、加法器实现、卡诺图化简、边沿检测、计数器设计、移位寄存器、测试平台搭建、状态机描述、时钟分频、多项式乘法等数字逻辑设计关键知识点,旨在帮助读者巩固理解并解决实际问题。
摘要由CSDN通过智能技术生成

目录

零、常撕题目

1、串并转换

2、时钟无毛刺切换

一、信号部分比特位选择

1、变量选择信号单个比特位

2、变量选择信号多个比特位

二、加法器

2.1 进位产生与结果计算

2.2 半加器实现全加器

2.3 串行进位加法器

三、卡诺图化简

四、MUX描述

 五、边沿相关

1、上升沿、下降沿、双边沿检测

2、双边沿采样器

3、 边沿检测易错点

 六、计数器 

1、BCD计数器

2、带load信号的计数器

七、移位寄存器

八、testbench

1、时钟

九、状态机

1、逻辑方程形式的状态机描述(独热码)

十、时钟分频

1、任意奇数倍分频且占空比50%

2、半整数分频

3、小数分频

十一、用四选一mux实现多项式乘法

​编辑

 十二、流水线形式乘法器

十三、求最小公倍数和最大公约数

 十四、仲裁器

1、高位首个1检测

2、低位首个1检测

3、 rr仲裁器

九十九、建议重做的题

2、 


零、常撕题目

1、串并转换

题目描述:    

        设计一个模块进行并串转换,要求每四位d输为转到一位dout输出,输出valid_in表示此时的输入有效

波形示意图:

clk为时钟
rst为低电平复位
d 信号输入

dout 信号输出
valid_in 表示输入有效

`timescale 1ns/1ns
module huawei5(
	input wire clk  ,
	input wire rst  ,
	input wire [3:0]d ,
	output wire valid_in ,
	output wire dout
	);

//*************code***********//
    reg [1:0] cnt;
    reg       vld_reg;
    reg [3:0] data_reg;
    
    always @(posedge clk or negedge rst)
        if(!rst)
            cnt    <= 2'h0;
        else
            cnt    <= cnt + 1'h1;
    always @(posedge clk or negedge rst)
        if(!rst)begin
            vld_reg    <= 1'b0;
            data_reg   <= 4'h0;
        end
        else if(cnt == 2'h3)begin
            vld_reg    <= 1'b1;
            data_reg    <= d[3:0];
        end
        else begin
            vld_reg    <= 1'b0;
            data_reg    <= data_reg << 1'b1;
        end
    assign valid_in    =    vld_reg;
    assign dout        =    data_reg[3];

        串并转换操作是非常灵活的操作,核心思想就是移位。串转并就是把1位的输入放到N位reg的最低位,然后N位reg左移一位,在把1位输入放到左移后的reg的最低位,这样循环,就可以得到,以最高位开始传输,最低位传输完成的N位数据了;并转串就是把并行的N位数据的最高位给1位输出,然后类似的循环左移就可以了。

2、时钟无毛刺切换

题目描述:    

        存在两个同步的倍频时钟clk0 clk1,已知clk0是clk1的二倍频,现在要设计一个切换电路,sel选择时候进行切换,要求没有毛刺。

信号示意图:

波形示意图:

clk0 clk1为时钟

rst为低电平复位

sel 是时钟选择器

clk_out 信号输出

`timescale 1ns/1ns

module huawei6(
	input wire clk0  ,
	input wire clk1  ,
	input wire rst  ,
	input wire sel ,
	output reg clk_out
);
//*************code***********//
reg sel1,sel0;
    always@(negedge clk1 or rst)
        if(!rst)
            sel1 <= 0;
        else
            sel1 <= !sel0 && sel;
    always@(negedge clk0 or rst)
        if(!rst)
            sel0 <= 0;
        else
            sel0 <= !sel1 && !sel;
    always@(*)
        clk_out = (sel1 & clk1) | (sel0 & clk0);

//*************code***********//
endmodule

        在两个电平相反的时候切换时钟,肯定有毛刺;电平相同的时候,即使不产生毛刺,时钟切换后的第一个时钟的周期或占空比也不是理想的。所以,为避免毛刺的产生,需要在两个时钟都为低电平的时候进行时钟切换。

一种典型的时钟切换电路如下所示。

        该电路利用时钟下降沿对时钟选择信号 sel_clk1 进行缓存。同时一个时钟选择信号对另一个时钟进行反馈控制,保证同一时刻只能有一路时钟有效。最后采用"或操作"将两路时钟合并,完成时钟切换的过程。

        使用的是负边沿触发的D触发器。这是为了确保在切换时钟源时,即使时钟正处在高电平,也不会影响输出变化

        考虑到选择信号有可能是异步信号,在选择路径上再插入一个上升沿触发D触发器,这是为了针对对两个异步时钟源产生的反馈信号以及异步信号SELECT,对选择信号进行同步处理,这样即使是两个异步的时钟源进行切换,也可以避免亚稳态的产生。

    reg     out_r1;
  reg     out1;
  reg     out_r0;
  reg     out0;
  ​
  always @(posedge clk1 or negedge rst_n)begin
      if(rst_n == 1'b0)begin
          out_r1 <= 0;
      end
      else begin
          out_r1 <= ~out0 & select;
      end
  end
  ​
  always @(negedge clk1 or negedge rst_n)begin
      if(rst_n == 1'b0)begin
          out1 <= 0;
      end
      else begin
          out1 <= out_r1;
      end
  end
  ​
  always @(posedge clk0 or negedge rst_n)begin
      if(rst_n == 1'b0)begin
          out_r0 <= 0;
      end
      else begin
          out_r0 <= ~select & ~out1;
      end
  end
  ​
  always @(negedge clk0 or negedge rst_n)begin
      if(rst_n == 1'b0)begin
          out0 <= 0;
      end
      else begin
          out0 <= out_r0;
      end
  end
  ​
  assign outclk = (out1 & clk1) | (out0 & clk0);

一、信号部分比特位选择

1、变量选择信号单个比特位

        Create a 1-bit wide, 256-to-1 multiplexer. The 256 inputs are all packed into a single 256-bit input vector. sel=0 should select in[0], sel=1 selects bits in[1], sel=2 selects bits in[2], etc.

module top_module(

    input [255:0] in,

    input [7:0] sel,

    output out );

    assign out = in[sel[7:0]];//in[sel[7:0]:sel[7:0]]的写法会报错

Endmodule

2、变量选择信号多个比特位

        Create a 4-bit wide, 256-to-1 multiplexer. The 256 4-bit inputs are all packed into a single 1024-bit input vector. sel=0 should select bits in[3:0], sel=1 selects bits in[7:4], sel=2 selects bits in[11:8], etc.

        in[sel*4 +: 4];//表示从sel*4起,选择比特序号大于sel*4 的 4 位比特,相当于[sel*4+3:sel*4];

module top_module(

    input [1023:0] in,

    input [7:0] sel,

    output [3:0] out );

    assign out[3:0] = in[sel*4 +: 4];//表示从sel*4起,选择比特序号大于sel*4 的 4 位比特,相当于[sel*4+3:sel*4];

endmodule

二、加法器

2.1 进位产生与结果计算

        Create a full adder. A full adder adds three bits (including carry-in) and produces a sum and carry-out.

    用 assign {cout,sum}= a+b+cin; 的形式同时计算进位和结果,写法巧妙值得借鉴。

module top_module( 
    input a, b, cin,
    output cout, sum );
    assign {cout,sum}= a+b+cin; //写法巧妙
endmodule

        Assume that you have two 8-bit 2's complement numbers, a[7:0] and b[7:0]. These numbers are added to produce s[7:0]. Also compute whether a (signed) overflow has occurred.

module top_module (
    input [7:0] a,
    input [7:0] b,
    output [7:0] s,
    output overflow
); //
    assign s = a[7:0] + b[7:0];
    assign overflow = (a[7]==b[7]) && (a[7] != s[7]);

endmodule

补码加法运算溢出判断的方法:​​​​​

  • [方法一]
    Xf、Yf分别两个数的符号位,Zf为运算结果符号位。
    当Xf =Yf =0(两数同为正),而Zf=1(结果为负)时,负溢出;
    当出现Xf =Yf =1(两数同为负),而Zf=0(结果为正),正溢出.
  • [方法二]
    Cs表示符号位的进位,Cp表示最高数值位进位,⊕表示异或。
    若 Cs⊕Cp =0 ,无溢出;
    若 Cs⊕Cp =1 ,有溢出。

2.2 半加器实现全加器

全加器_牛客题霸_牛客网

①第一个半加器:先将A和B用加起来,生成和是s[0]和进位信号c[0];

②第二个半加器:第一个半加器生成的和s[0]与Ci用半加器相加,得到的和s[1]即为全加器的和S;

③全加器进位信号的生成是这样:两次半加器产生的进位信号有一个为1,则全加器的进位信号Co为1。

    add_half add_half1 (A ,      B , s_tmp ,c_tmp);
    add_half add_half2 (s_tmp , Ci , S     ,c_tmp2);
    assign Co = c_tmp|| c_tmp2;

2.3 串行进位加法器

串行进位加法器_牛客题霸_牛客网

用半加器搭建全加器,然后例化多个全加器实现串行进位加法器。

半加器:结果=a^b  进位=a&b

三、卡诺图化简

        Implement the circuit described by the Karnaugh map below.

        Try to simplify the k-map before coding it. Try both product-of-sums and sum-of-products forms. We can't check whether you have the optimal simplification of the

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值