• 【Verilog刷题篇】硬件工程师从0到入门1|基础语法入门


    前言

    • 硬件工程师近年来也开始慢慢吃香,校招进大厂年薪总包不下30-40w的人数一大把!而且大厂人数并没有饱和!
      - 本期是【Verilog刷题篇】硬件工程师从0到入门1|基础语法入门,有不懂的地方可以评论进行讨论!
    • 推荐给大家一款刷题、面试的神器,我也是用这一款神器进行学习Verilog硬件代码的!
    • ~链接如下:刷题面试神器跳转链接
    • 也欢迎大家去牛客查看硬件工程师招聘职位的各类资料,并进行提前批投递面试!
    • 小白新手可以通过该神器进行日常的刷题、看大厂面经、学习计算机基础知识、与大牛面对面沟通~ 刷题的图片已经放在下面了~

    在这里插入图片描述

    Q1:四选一多路器

    题目描述:
    制作一个四选一的多路选择器,要求输出定义上为线网类型状态转换:
    d0 11
    d1 10
    d2 01
    d3 00
    在这里插入图片描述

    输入描述:输入信号 d1,d2,d3,d4 sel 类型 wire
    输出描述:输出信号 mux_out 类型 wire

    相关提示:

    • 线网类型只能使用连续赋值语句进行赋值;
    • 使用三元运算符 ?: 来实现四个信号的选择;
    • 实现思路为:首先判断sel[0]的数值,再判断sel[1]的数值,即可判断出应当选择哪一个信号;
    • 此外应当看清时序电路图中sel的数值和四个信号之间的对应关系,下表为该题目中对应关系。

    案例代码:

    `timescale 1ns/1ns
    module mux4_1(
    input [1:0]d1,d2,d3,d0,
    input [1:0]sel,
    output[1:0]mux_out
    );
        assign mux_out = sel[0]?(sel[1]?d0:d2):(sel[1]?d1:d3);
        
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Q2:异步复位的串联T触发器

    题目描述:用verilog实现两个串联的异步复位的T触发器的逻辑,结构如图:

    在这里插入图片描述
    在这里插入图片描述

    输入描述:输入信号 data, clk, rst 类型 wire 在testbench中,clk为周期5ns的时钟,rst为低电平复位
    输出描述:输出信号 q 类型 reg

    案例代码:

    //先设计单独的t触发器,然后通过例化的方式串起来。 注意哦 output reg q 改成output wireq 。这是因为连线都要用wire 型
    `timescale 1ns/1ns
    module Tff_2 (
    input wire data, clk, rst,
    output wire q  
    );
    //*************code***********//
        wire q1;
        TFF TFF_inst1(
            .data    (data), 
            .clk     (clk), 
            .rst     (rst),
            .q       (q1)      
        );
        TFF TFF_inst2(
            .data    (q1), 
            .clk     (clk), 
            .rst     (rst),
            .q       (q)      
        );    
    //*************code***********//
    endmodule
    //T触发器设计
    module TFF(
        input wire data, clk, rst,
        output reg q    
    );
        always @(posedge clk or negedge rst)begin
            if(!rst)
                q <= 1'b0;
            else if(data == 1'b0)
                q <= q;
            else if(data == 1'b1)
                q <= ~q;     
        end
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    Q3:移位运算与乘法

    题目描述:现在需要对输入的32位数据进行奇偶校验,根据sel输出检测结果
    在这里插入图片描述
    在这里插入图片描述

    输入描述:输入信号 bus sel 类型 wire
    输出描述:输出信号 check 类型 wire

    案例代码:

    `timescale 1ns/1ns
    module odd_sel(
    input [31:0] bus,
    input sel,
    output check
    );
    //*************code***********//
    wire check_tmp;
        
        // 单目运算符
        assign check_tmp = ^bus;
      //  assign check = (sel == 1'b1) ? check_tmp : ~check_tmp;
        
        reg check_reg;
        always @ (*) begin
            if(sel) begin
                check_reg = check_tmp;
            end
            else begin
                check_reg = ~check_tmp;
            end 
        end 
        
        assign check = check_reg;
    
    //*************code***********//
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    Q4:移位运算与乘法

    题目描述:已知d为一个8位数,请在每个时钟周期分别输出该数乘1/3/7/8,并输出一个信号通知此时刻输入的d有效(d给出的信号的上升沿表示写入有效)
    在这里插入图片描述在这里插入图片描述

    输入描述:输入信号 d, clk, rst 类型 wire 在testbench中,clk为周期5ns的时钟,rst为低电平复位
    输出描述:输出信号 input_grant out 类型 reg

    案例代码:

    //要输出有效输入标志input_grant,考虑定义一个寄存器变量(cnt)用于计数。
    //计数最大值就是乘法运算次数(四次),在一个计数周期内输入保持不变。
    //当计数器为0时,input_grant=1,其余时刻保持低电平;将出入d赋值给寄存器reg_d;
    //当计数器达到最大值时,计数器清零,其中计数器每次加一对应一次乘法运算。
    `timescale 1ns/1ns
    module vl4 (
    input [7:0]d ,
    input clk,
    input rst,
    output reg input_grant,
    output reg [10:0]out
    );
    //*************code***********//
        reg [1:0] cnt;
        reg [7:0] reg_d;
    //*******计数器初始化及赋值*******//    
    always@(posedge clk or negedge rst)
        if(rst == 1'b0)
            cnt <= 2'd0;
        else if(cnt == 2'd3)
            cnt <= 2'd0;
        else 
            cnt <= cnt + 1'b1;
    //***数据寄存器(reg_d)和输入有效标志(input_grant)初始化及赋值***// 
    always@(posedge clk or negedge rst)
        if(rst == 1'b0)begin
            reg_d <= 8'd0;
            input_grant <= 1'b0;
        end
        else if(cnt == 2'd0)begin
            reg_d <= d;
            input_grant <= 1'b1;
        end
        else begin
            reg_d <= reg_d;
            input_grant <= 1'b0;
        end
    //****乘法运算****//       
    always@(posedge clk or negedge rst)
        if(rst == 1'b0) 
            out <= 11'd0;
        else case (cnt)
            2'd0 : out <= d;
            2'd1 : out <= (reg_d<<2)-reg_d;
            2'd2 : out <= (reg_d<<3)-reg_d;
            2'd3 : out <= (reg_d<<3);
            default : out <= 11'd0;
        endcase
    //*************code***********//
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    Q5:位拆分与运算

    题目描述:
    现在输入了一个压缩的16位数据,其实际上包含了四个数据[3:0] [7:4] [11:8] [15:12],
    现在请按照sel选择输出四个数据的相加结果,并输出valid_out信号(在不输出时候拉低)
    0: 不输出且只有此时的输入有效
    1:输出[3:0]+[7:4]
    2:输出[3:0]+[11:8]
    3:输出[3:0]+[15:12]
    在这里插入图片描述
    在这里插入图片描述

    输入描述:输入信号 d, clk, rst, 类型 wire,在testbench中,clk为周期5ns的时钟,rst为低电平复位
    输出描述:输出信号 validout out ,类型 reg 。

    案例代码:

    //题中看到对于sel的不同情况,有几种不同的输出,首先考虑到用case语句。
    //要注意的是,仅当sel为0时,输入信号有效,因此需要一个寄存器data_temp,在sel为0时对输入信号进行锁存。
    //下一步编写代码:
    //复位时,三个信号受到影响,即data_temp清零、validout清零、输出out清零;
    //sel为0时,将输入的值锁存到data_temp中,同时validout拉低,输出out为0;
    //sel为1时,validout拉高,同时将锁存后的data_temp按位进行输出out的运算;
    //sel为2时,validout拉高,同时将锁存后的data_temp按位进行输出out的运算;
    //sel为3时,validout拉高,同时将锁存后的data_temp按位进行输出out的运算。
    `timescale 1ns/1ns
    
    module data_cal(
    input clk,
    input rst,
    input [15:0]d,
    input [1:0]sel,
    
    output reg [4:0]out,
    output reg validout
    );
        reg [15:0]data_temp;
        always@(posedge clk or negedge rst)
            if(!rst)begin
                out<=5'd0;
                validout<=1'b0;
                data_temp<=15'd0;
            end
            else case(sel)
                0:
                    begin
                        data_temp<=d;
                        out[4:0]<=5'd0;
                        validout<=1'b0;
                    end
                1:
                    begin
                        validout<=1'b1;
                        out[4:0]<=data_temp[3:0]+data_temp[7:4];
                    end
                2:
                    begin
                        validout<=1'b1;
                        out[4:0]<=data_temp[3:0]+data_temp[11:8];
                    end
                3:
                    begin
                        validout<=1'b1;
                        out[4:0]<=data_temp[3:0]+data_temp[15:12];
                    end
                default:
                    begin
                        validout<=1'b0;
                        out[4:0]<=5'd0;
                    end
            endcase
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    总结:小白跟大牛都在用的好平台!

    • 硬件工程师近年来也开始慢慢吃香,校招进大厂年薪总包不下30-40w的人数一大把!而且大厂人数并没有饱和!
      - 本期是【Verilog刷题篇】硬件工程师从0到入门1|基础语法入门,有不懂的地方可以评论进行讨论!

    快来点击链接进行跳转注册,开始你的保姆级刷题之路吧!刷题打怪码神之路

    另外这里不仅仅可以刷题,你想要的这里都会有,十分适合小白和初学者入门学习~
    1、算法篇(398题):面试必刷100题、算法入门、面试高频榜单
    2、数据结构篇(300题):都是非常经典的链表、树、堆、栈、队列、动态规划等
    3、语言篇(500题):C/C++、java、python入门算法练习
    4、SQL篇(82题):快速入门、SQL必知必会、SQL进阶挑战、面试真题
    5、大厂笔试真题:字节跳动、美团、百度、腾讯…掌握经验不在惧怕面试!

    在这里插入图片描述

  • 相关阅读:
    直流有刷电机开环调速基于STM32F302R8+X-NUCLEO-IHM07M1(一)
    CleanMyMac X的免费版电脑系统瘦身工具
    Kotlin 协程之取消与异常处理探索之旅(上)
    redis中value/String
    Python3操作文件系列(三):OpenPyXl模块三大对象操作Excel文件
    积分商城游戏设置的基本要点
    电脑重装系统后如何给系统磁盘扩容空间
    双坐标轴柱状图
    js:截取url上的最后一位参数的键值
    Jenkins代理模式配置Maven工程
  • 原文地址:https://blog.csdn.net/weixin_51484460/article/details/126089370