• 【牛客网刷题系列 之 Verilog快速入门】~ 多功能数据处理器、求两个数的差值、使用generate…for语句简化代码、使用子模块实现三输入数的大小比较


    1. VL6 多功能数据处理器

    题目来源:牛客网

    1.1 题目描述

    根据指示信号select的不同,对输入信号a,b实现不同的运算。输入信号a,b为8bit有符号数,当select信号为0,输出a;当select信号为1,输出b;当select信号为2,输出a+b;当select信号为3,输出a-b.

    1.1.1 信号示意图

    在这里插入图片描述

    1.1.2 波形示意图

    1.1.3 输入描述

    clk:系统时钟
    rst_n:复位信号,低电平有效
    a,b:8bit位宽的有符号数
    select:2bit位宽的无符号数

    1.1.4 输出描述

    c:9bit位宽的有符号数

    1.2 解题思路

    通过case语句完成多分支的运算,根据select不同值进行区分即可。

    1.3 代码实现

    `timescale 1ns/1ns
    module data_select(
    	input clk,
    	input rst_n,
    	input signed[7:0]a,
    	input signed[7:0]b,
    	input [1:0]select,
    	output reg signed [8:0]c
    );
        always @ (posedge clk or negedge rst_n) begin
            if(!rst_n) begin
               c <= 9'd0; 
            end
            else begin
                case (select)
                    2'b00 : begin
                        c <= {a[7], a}; 
                    end
                    2'b01 : begin
                        c <= {b[7], b}; 
                    end
                    2'b10 : begin
                        c <= {a[7], a} + {b[7], b}; 
                    end
                    2'b11 : begin
                        c <= {a[7], a} - {b[7], b}; 
                    end
                    default : begin
                       c <= 9'd0; 
                    end
                endcase
            end
        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

    1.4 测试文件

    待更。。。

    1.5 仿真波形

    待更。。。

    =========================================================================

    2. VL7 求两个数的差值

    题目来源:牛客网

    2.1 题目描述

    根据输入信号a,b的大小关系,求解两个数的差值:输入信号a,b为8bit位宽的无符号数。如果a>b,则输出a-b,如果a≤b,则输出b-a。

    2.1.1 信号示意图

    在这里插入图片描述

    2.1.2 波形示意图

    2.1.3 输入描述

    clk:系统时钟
    rst_n:复位信号,低电平有效
    a,b:8bit位宽的无符号数

    2.1.4 输出描述

    c:8bit位宽的无符号数

    2.2 解题思路

    和第一个题比较类似,只不过这个题目只有两种情况,直接用if语句块就解决了。

    2.3 代码实现

    `timescale 1ns/1ns
    module data_minus(
    	input clk,
    	input rst_n,
    	input [7:0]a,
    	input [7:0]b,
    
    	output  reg [8:0]c
    );
        always @ (posedge clk or negedge rst_n) begin
            if(!rst_n) begin
               c <= 9'd0; 
            end
            else begin
                if(a > b) begin
                   c <= a - b; 
                end
                else begin
                   c <= b - a; 
                end
            end
        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

    2.4 测试文件

    待更。。。

    2.5 仿真波形

    待更。。。

    =========================================================================

    3. VL8 使用generate…for语句简化代码

    3.0 前言

    题目来源:牛客网

    3.0.1 知识点

    考察generate…for…的用法,老办法,话不多说,插眼,传送门

    3.1 题目描述

    在某个module中包含了很多相似的连续赋值语句,请使用generata…for语句编写代码,替代该语句,要求不能改变原module的功能。
    使用Verilog HDL实现以上功能并编写testbench验证。

    module template_module(
    input [7:0] data_in,
    output [7:0] data_out
    );
    assign data_out [0] = data_in [7];
    assign data_out [1] = data_in [6];
    assign data_out [2] = data_in [5];
    assign data_out [3] = data_in [4];
    assign data_out [4] = data_in [3];
    assign data_out [5] = data_in [2];
    assign data_out [6] = data_in [1];
    assign data_out [7] = data_in [0];

    endmodule

    3.1.1 信号示意图

    无。

    3.1.2 波形示意图

    3.1.3 输入描述

    data_in:8bit位宽的无符号数

    3.1.4 输出描述

    data_out:8bit位宽的无符号数

    3.2 解题思路

    该题基本语法考察。看前言部分传送门即可。

    3.3 代码实现

    `timescale 1ns/1ns
    module gen_for_module( 
        input [7:0] data_in,
        output [7:0] data_out
    );
    
        genvar i;
        generate
            begin : practice
                for(i = 0; i < 8; i = i+1) 
                    assign data_out[i] = data_in[7-i];
            end
        endgenerate
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3.4 测试文件

    待更。。。

    3.5 仿真波形

    待更。。。

    =========================================================================

    4. VL9 使用子模块实现三输入数的大小比较

    4.0 前言

    题目来源:牛客网

    4.0.1 知识点

    模块之间的相互调用。

    4.1 题目描述

    在数字芯片设计中,通常把完成特定功能且相对独立的代码编写成子模块,在需要的时候再在主模块中例化使用,以提高代码的可复用性和设计的层次性,方便后续的修改。

    请编写一个子模块,将输入两个8bit位宽的变量data_a,data_b,并输出data_a,data_b之中较小的数。并在主模块中例化,实现输出三个8bit输入信号的最小值的功能。

    4.1.1 信号示意图

    无。

    4.1.2 波形示意图

    4.1.3 输入描述

    clk:系统时钟
    rst_n:异步复位信号,低电平有效
    a,b,c:8bit位宽的无符号数

    4.1.4 输出描述

    d:8bit位宽的无符号数,表示a,b,c中的最小值

    4.2 解题思路

    该题模块调用倒是不难,就是分别写一下模块(一般情况下,不同模块是要写在不同的文件中的,但写在一个文件中也是可以的)。调用之前,需要先例化该模块!!!

    但这个题比较容易出错的地方在于,子模块用时序逻辑和组合逻辑写,在主模块中处理方式是不一样的,我们细细看一下:

    1. 如果你子模块用的是时序逻辑写的话,你主模块必须实例化三次,如果你想实例化两次比较3个输入abc的话,你就会发生其中2个信号是在同一周期T下的,而另外那个信号却在周期T+1下,造成比较混乱。
    2. 如果你子模块用的是组合逻辑写的话,你主模块可以只实例化2次子模块,但是你得完成打两拍的动作等待一下,最后一起输出。

    4.3 代码实现

    4.3.1 子模块用的是时序逻辑写的

    `timescale 1ns/1ns
    module main_mod(
    	input clk,
    	input rst_n,
    	input [7:0]a,
    	input [7:0]b,
    	input [7:0]c,
    	
    	output [7:0]d
    );
        wire [7:0] ab_min_reg;
        wire [7:0] ac_min_reg;
        
        sub_mod u1(
            .clk(clk),
            .rst_n(rst_n),
            .a(a),
            .b(b),
            .c(ab_min_reg)
        );
        sub_mod u2(
            .clk(clk),
            .rst_n(rst_n),
            .a(a),
            .b(c),
            .c(ac_min_reg)
        );
        sub_mod u3(
            .clk(clk),
            .rst_n(rst_n),
            .a(ab_min_reg),
            .b(ac_min_reg),
            .c(d)
        );
        
    
    endmodule
    //子模块(时序逻辑实现)
    module sub_mod(
        input clk,
    	input rst_n,
    	input [7:0]a,
    	input [7:0]b,
        
    	output reg [7:0]c
    );
        always @ (posedge clk or negedge rst_n) begin
            if(!rst_n) begin
               c <= 8'd0; 
            end
            else begin
                if(a >= b) begin
                   c <= b; 
                end
                else begin
                   c <= a; 
                end
            end
        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
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    4.3.2 子模块用的是组合逻辑写的

    `timescale 1ns/1ns
    module main_mod(
    	input clk,
    	input rst_n,
    	input [7:0]a,
    	input [7:0]b,
    	input [7:0]c,
    	
    	output [7:0]d
    );
        
        wire [7:0] tmp1;    // a b 的最小值
        child_mod U0(
            .a        ( a ),
            .b        ( b ),
            .d        ( tmp1 )
        );
        
        wire [7:0] tmp2;    // a c 的最小值
        child_mod U1(
            .a        ( tmp1 ),
            .b        ( c ),
            .d        ( tmp2 )
        );
        
        reg [7:0] d_reg;
        reg [7:0] d_reg2;
        always @ (posedge clk&nbs***bsp;negedge rst_n)
            begin
                if( ~rst_n ) begin
                    d_reg <= 8'b0;
                    d_reg2 <= 8'b0;
                end 
                else begin
                    d_reg <= tmp2;
                    d_reg2 <= d_reg;
                end 
            end
        assign d = d_reg2;
    
    endmodule
    
    module child_mod(
            input [7:0]a,
            input [7:0]b,
            output [7:0]d
        );
        assign d = (a>b) ? b : a;
    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

    4.4 测试文件

    待更。。。

    4.5 仿真波形

    待更。。。

    声明

    本人所有系列的文章,仅供学习,不可商用,如有侵权,请告知,立删!!!

    本人主要是记录学习过程,以供自己回头复习,再就是提供给后人参考,不喜勿喷!!!

    如果觉得对你有用的话,记得收藏+评论!!!

  • 相关阅读:
    el-upload 上传视频时,动态截取视频第一帧画面作为封面展示
    NumPy模块:Python科学计算神器之一
    Luckysheet:一个纯前端的excel在线表格
    【Linux】进程等待
    字母异位词分组:分类同字母异序词
    pyecharts 主题:颜色渐变实例(线性渐变)
    cpp primer plus笔记06-函数
    防火墙基础之H3C防火墙分支与分支之间双向地址转换
    为什么我抓不到baidu的数据包
    Golang语言设计模式的实现—工厂模式
  • 原文地址:https://blog.csdn.net/qq_40549426/article/details/125552574