• 刷题:牛客-快速入门篇


    前言

    正文

    VL4 移位运算与乘法

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

    在这里插入图片描述
    乘法:将d进行移位相加

    //4、移位运算与乘法
    `timescale 1ns/1ns
    module multi_sel(
    	input [7:0]d ,
    	input clk,//200MHZ,5ns
    	input rst,
    	output  reg input_grant,
    	output  reg [10:0]out
    );
    
    reg [1:0] cnt_3;
    always@(posedge clk or negedge rst)begin
    	if(!rst)begin
    		cnt_3 <= 2'd0;
    	end
    	else if(cnt_3 == 2'd3)begin
    		cnt_3 <= 2'd0;
    	end
    	else
    		cnt_3 <= cnt_3 + 2'd1;
    end
    
    reg [7:0] d_reg;
    
    always@(posedge clk or negedge rst)begin
    	if(!rst)begin
    		input_grant = 1'd0;
    		d_reg 		= 8'd0;
    		out			= 8'd0;
    	end
    	else begin
    	
    	case(cnt_3)
    		2'd0:begin
    			input_grant = 1'd1;
    			d_reg 		= d;//寄存数据
    			out			= d;
    		end
    		2'd1:begin
    			input_grant = 1'd0;
    			out 		= d_reg + (d_reg<<1'd1);//3
    		end
    		2'd2:begin
    			input_grant = 1'd0;
    			out 		= d_reg + (d_reg<<1'd1) + (d_reg<<2'd2) ;//7
    		end
    		2'd3:begin
    			input_grant = 1'd0;
    			out 		= (d_reg<<3'd3);//8
    		end		
    	default:;
    	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
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    VL5 位拆分与运算

    在这里插入图片描述

    
    `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
    );
    //*************code***********//
    
    reg [15:0] d_reg;
    always@(posedge clk or negedge rst)begin
    	if(!rst)begin
    		out <= 5'd0;
    		validout <= 1'd0;
    		d_reg <= 16'd0;
    	end
    	else
    	case(sel)
    	2'd0: begin
    		validout <= 1'd0;
    		d_reg <= d;//锁存数据
    		out <= 5'd0;
    		end
    	2'd1: begin
    		validout <= 1'd1;
    		out <= d_reg[3:0] + d_reg[7:4];
    		end
    	2'd2: begin
    		validout <= 1'd1;
    		out <= d_reg[3:0] + d_reg[11:8];
    		end
    	2'd3: begin
    		validout <= 1'd1;
    		out <= d_reg[3:0] + d_reg[15:12];
    		end
    	default:;
    	endcase
    end
    
    
    //*************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

    在这里插入图片描述

    VL6 多功能数据处理器

    根据指示信号select的不同,对输入信号a,b实现不同的运算。输入信号a、b为8bit有符号数,

    当select[1;0] =0,输出a;
    当select[1;0] =1,输出b;
    当select[1;0] =2,输出a+b;
    当select[1;0] =3,输出a-b。
    因为输入输出都已经直接定义了signed有符号数类型,所以直接相加、相减也没有问题,不会出现运算错误。

    有符号数+有符号数=有符号数,但是如果表达式中有一个无符号数,则所有的操作数都会被强行转换为无符号数
    两种解决方法

    (1)涉及到有符号数运算时,和有符号相关的输入、输出、中间变量均定义成signed有符号数,这样全部遵循有符号数运算规则;

    (2)用位拼接符补齐符号位;

    // VL6 多功能数据处理器
    // 1.有符号数的减法运算
    // 2.选择器
    // 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
    	case(select)
    		2'd0: c <= a;
    		2'd1: c <= b;
    		2'd2: c <= a + b;
    		2'd3: c <= a - b;
    	default:;
    	endcase
    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

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

    参考笔记,总结详细

    作用上

    和for是一样的;

    区别

    (1)generate for的循环变量必须用genvar声明,for的变量可以用reg、integer整数等多种类型声明;

    (2)for只能用在always块里面,generate for可以做assign赋值,用always块话always写在generate for里;

    (3)generate for后面必须给这个循环起一个名字,for不需要;

    (4)generate for还可以用于例化模块
    格式
    genvar i;
    generate
    for(i=0;表达式2;表达式3)
    begin :起个名字
    …;
    end
    endgenerate

    // VL8 使用generate…for语句简化代码
    `timescale 1ns/1ns
    module gen_for_module( 
        input [7:0] data_in,
        output [7:0] data_out
    );
    
    genvar i;
    generate
    
    for (i = 0; i < 8 ; i=i+1)
    begin: myloop
    	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
    • 15
    • 16
    • 17
    • 18
    • 19

    等价于
    因此for循环里的语句也是并行的

    
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

    在这里插入图片描述

    `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
    );
    wir [7:0] min_ab;
    wir [7:0] min_ac;
    wir [7:0] min_abc;
    
    sub_mod sub_mod_inst_01(
    	.clk(clk),
    	.rst_n(rst_n),
    	.a(a),
    	.b(b),
    	
    	.d(min_ab)
    );
    
    sub_mod sub_mod_inst_02(
    	.clk(clk),
    	.rst_n(rst_n),
    	.a(a),
    	.b(c),
    	
    	.d(min_ac)
    );
    
    sub_mod sub_mod_inst_03(
    	.clk(clk),
    	.rst_n(rst_n),
    	.a(min_ab),
    	.b(min_ac),
    	
    	.d(min_abc)
    );
    
    assign d = min_abc;
    endmodule
    
    //子模块
    module sub_mod(
    	input clk,
    	input rst_n,
    	input [7:0]a,
    	input [7:0]b,
    	
    	output reg[7:0]d
    );
    always@(posedge clk or negedge rst_n)begin
    	if(!rst_n )begin
    		d <= 8'd0;
    	end
    	else if(a>b)begin
    		d <= b;
    	end
    	else if(a<b)
    		d <= a;
    	else
    		d <= d;
    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
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    VL10 使用函数实现数据大小端转换

    function笔记
    实现向量位转换
    HDLBits类似题

    `timescale 1ns/1ns
    module function_mod(
    	input clk,
    	input rst_n,
    	input [3:0]a,
    	input [3:0]b,
    	
    	output  [3:0]c,
    	output  [3:0]d
    );
    
    assign c = rst_n ? change_bit(a) : 1'd0;
    assign d = rst_n ? change_bit(b) : 1'd0;
    
    function [3:0]change_bit;
    input [3:0]data_in;
    
    integer i;
    for (i = 0; i < 4 ; i=i+1)
    begin: myloop
        change_bit[i] = data_in[3-i];
    end
    
    endfunction
    
    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

    // VL11 4位数值比较器电路

    题目中规定了要用门级描述:参考答案
    在这里插入图片描述
    首先根据真值表写出表达式
    然后画出对应的电路图
    在这里插入图片描述
    最后可以用Verilog描述出上面的电路
    在这里插入图片描述

    // VL11 4位数值比较器电路
    `timescale 1ns/1ns
    
    module comparator_4(
    	input		[3:0]       A   	,
    	input	   [3:0]		B   	,
     
     	output	 wire		Y2    , //A>B
    	output   wire        Y1    , //A=B
        output   wire        Y0      //A
    );
    // 方法一:使用比较大小的方法,虽然能运行出来,但是题目要求是欧诺个门级描述
    // 		   因此最好不适用比较大小的方法
    /* assign Y2 = ((A[3]>B[3])||(A[2]>B[2])||((A[1]>B[1]) && (A[2]==B[2]) && (A[3]==B[3]))||((A[0]>B[0])&&(A[2]==B[2])&&(A[1]==B[1]) && (A[3]==B[3])))?1'd1:1'd0;
    assign Y0 = ((A[3]
    
    
    //方法二
    
    not iv0(iv0_o, B[0]),
        iv1(iv1_o, B[1]),
        iv2(iv2_o, B[2]),
        iv3(iv3_o, B[3]),
        iv4(iv4_o, A[0]),
        iv5(iv5_o, A[1]),
        iv6(iv6_o, A[2]),
        iv7(iv7_o, A[3]);
        
    and ad0(
    , iv0_o, A[0]),
        ad1(ad1_o, iv1_o, A[1]),
        ad2(ad2_o, iv2_o, A[2]),
        ad3(ad3_o, iv3_o, A[3]),
        
        ad4(ad4_o, ad0_o, xnr0_o, xnr1_o, xnr2_o),
        ad5(ad5_o, ad1_o, xnr1_o, xnr2_o),
        ad6(ad6_o, ad2_o, xnr2_o),
        
        ad7(ad7_o, iv4_o, B[0]),
        ad8(ad8_o, iv5_o, B[1]),
        ad9(ad9_o, iv6_o, B[2]),
        ad10(ad10_o, iv7_o, B[3]),
        
        ad11(ad11_o, ad7_o, xnr0_o, xnr1_o, xnr2_o),
        ad12(ad12_o, ad8_o, xnr1_o, xnr2_o),
        ad13(ad13_o, ad9_o, xnr2_o),
        ad14(Y1, xnr2_o, xnr1_o, xnr0_o, xnr3_o);
        
    xnor xnr0(xnr0_o, A[1], B[1]),  
         xnr1(xnr1_o, A[2], B[2]),   
         xnr2(xnr2_o, A[3], B[3]),   
         xnr3(xnr3_o, A[0], B[0]);  
    
    or or0(Y2, ad3_o, ad6_o, ad5_o, ad4_o),
       or1(Y0, ad10_o, ad13_o, ad12_o, ad11_o) ;    
        
    
    
    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
    • 61
  • 相关阅读:
    解开C语言的秘密《关键字》(第六期)
    shell脚本(五)函数
    Java----内部类、外部类、匿名对象、匿名对象的创建
    C++时间转换
    使用 Kind 快速体验 KubeGems
    【持续置顶,使用期间保持一直更新】Ubuntu 20.0.4 使用经验分享
    人力资源数字化转型,是企业高质量发展的关键
    八大排序之插入排序
    使用 PointNet 进行3D点集(即点云)的分类
    基于时延估计的动力型下肢假肢分段控制策略研究
  • 原文地址:https://blog.csdn.net/m0_46830519/article/details/125900022