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

目录:

  • 1. VL6 多功能数据处理器
    • 1.1 题目描述
      • 1.1.1 信号示意图
      • 1.1.2 波形示意图
      • 1.1.3 输入描述
      • 1.1.4 输出描述
    • 1.2 解题思路
    • 1.3 代码实现
    • 1.4 测试文件
    • 1.5 仿真波形
  • 2. VL7 求两个数的差值
    • 2.1 题目描述
      • 2.1.1 信号示意图
      • 2.1.2 波形示意图
      • 2.1.3 输入描述
      • 2.1.4 输出描述
    • 2.2 解题思路
    • 2.3 代码实现
    • 2.4 测试文件
    • 2.5 仿真波形
  • 3. VL8 使用generate…for语句简化代码
    • 3.0 前言
      • 3.0.1 知识点
    • 3.1 题目描述
      • 3.1.1 信号示意图
      • 3.1.2 波形示意图
      • 3.1.3 输入描述
      • 3.1.4 输出描述
    • 3.2 解题思路
    • 3.3 代码实现
    • 3.4 测试文件
    • 3.5 仿真波形
  • 4. VL9 使用子模块实现三输入数的大小比较
    • 4.0 前言
      • 4.0.1 知识点
    • 4.1 题目描述
      • 4.1.1 信号示意图
      • 4.1.2 波形示意图
      • 4.1.3 输入描述
      • 4.1.4 输出描述
    • 4.2 解题思路
    • 4.3 代码实现
      • 4.3.1 子模块用的是时序逻辑写的
      • 4.3.2 子模块用的是组合逻辑写的
    • 4.4 测试文件
    • 4.5 仿真波形
  • 声明

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 信号示意图

【牛客网刷题系列 之 Verilog快速入门】~ 多功能数据处理器、求两个数的差值、使用generate…for语句简化代码、使用子模块实现三输入数的大小比较_第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.4 测试文件

待更。。。

1.5 仿真波形

待更。。。

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

2. VL7 求两个数的差值

题目来源:牛客网

2.1 题目描述

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

2.1.1 信号示意图

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

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

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

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 信号示意图

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

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

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

4.4 测试文件

待更。。。

4.5 仿真波形

待更。。。

声明

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

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

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

你可能感兴趣的:(FPGA刷题系列,fpga开发,集成测试)