FPGA刷题P2:多功能数据处理器、求两个数的差值、使用generate...for语句简化代码、使用子模块实现三输入数的大小比较、使用函数实现数据大小端转化

(2条消息) FPGA刷题P1:4选1多路选择器、异步复位的串联T触发器、奇偶校验、移位拼接乘法_居安士的博客-CSDN博客

题目是牛客网的编程题,part1链接在上面,书接上文今天分享part2 !


目录

多功能数据处理器

求两个数的差值

 使用generate...for语句简化代码

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

 使用函数实现数据大小端转化


多功能数据处理器

 这一题主要考察的是有符号数的编程,有符号数需要注意以下两点:

(1)在定义的时候,有符号数用 signed[ : ],例如output reg signed [8:0]c

(2)有符号数的最高位是符号位,为+或者-

`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'b0;
        end
        else begin
            case(select)
                2'd0:c<={a[7],a};//最高位为符号位
                2'd1:c<={b[7],b};
                2'd2:c<={a[7],a}+{b[7],b};
                2'd3:c<={a[7],a}-{b[7],b};
                default:  c<=9'b0;
            endcase
        end
    end
      
endmodule

求两个数的差值

 这个题用if-else语句就可以解决,代码如下:

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'b0;
        end
        else begin
            if(a>b)begin
                c<=a-b;
            end
            else if(a<b)begin
                c<=b-a;
            end
        end
    end
    
endmodule

 使用generate...for语句简化代码

 这个题主要考察Verilog中genrate—for语句的使用,和c语言相似但是不同,流程如下:

genvar 变量;

generate for(变量初始值;变量跳转;变量+1)

        begin:gen_变量

                语句;

        end

endgenerate·

注意:

使用generate —for语句之前必须先用genvar语句声明变量

generate —for语句之后的begin:需加一个变量(名称无所谓)

generate —for 还需要endgenerate作为结束

代码如下:

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:gen_i
            assign data_out[i]=data_in[7-i];
        end
    endgenerate
        
  
endmodule

顺便总结一下for语句的使用:

integer 变量;

for(变量初始值;变量跳转;变量+1)

        begin

                语句;

        end

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

 

 这个题主要考察我们对于“例化”的使用

按照题目要求,我们需要首先自己写一个子模块,实现2个数比较取最小值的功能

然后例化3次子模块,把主模块输入的3个数abc,a和b比输出较小值temp1,a和c比输出较小值temp2,再把temp1和temp2进行比较,得到最小值即为输出

这个题目告诉我们,一个子模块可以多次进行例化,只需要修改例化名称即可

例化子模块中( )内的输入输出是主模块的变量,是可以变化名称的

代码如下:

//主模块通过利用子模块的两两比较,输出3个数值中的最小值
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] temp1;
    wire [7:0] temp2;
     
    junior_mod u1(
        .clk(clk),
        .rst_n(rst_n),
        .a(a),
        .b(b),
        .c(temp1)//a与b比较最小值是temp1
);
    junior_mod u2(
        .clk(clk),
        .rst_n(rst_n),
        .a(a),
        .b(c),
        .c(temp2)//a与c比较最小值是remp2
);
        junior_mod u3(
            .clk(clk),
            .rst_n(rst_n),
            .a(temp1),
            .b(temp2),
            .c(d)//temp1与temp2比较最小值是d
);
    
endmodule


//子模块实现2值相比
module junior_mod(
	input clk,
	input rst_n,
	input [7:0]a,
	input [7:0]b,
    output [7:0]c
);

    reg [7:0]c_reg;
    
    always@(posedge clk or negedge rst_n )begin
        if(~rst_n)begin
            c_reg<=8'd0;
        end
        else begin
            if(a>b)begin
                c_reg<=b;
            end
            else if(b>a)begin
                c_reg<=a;
            end
        end
    end
    
    assign c=c_reg;
endmodule

 使用函数实现数据大小端转化

 这个题考察我们的结构化设计,需要我们自己构建函数和任务,function和task的使用方法如下:

任务(task)

(1)通常用于调试,或对硬件进行行为描述

(2)可以包含时序控制(#延迟,, wait)

(3)可以有input, output, 和linout参数

(4)可以调用其他任务或函数

function(任务)

(1)通常用于计算,或描述组合逻辑
(2)不能包含任何延迟;函数仿真时间为0

(3)只含有Input参数并由函数名返回一个结果

(4)可以调用其他函数,但不能调用任务

这道题使用function代码如下:

module function_mod(
    input clk,
    input rst_n,
	input [3:0]a,
	input [3:0]b,
	
	output [3:0]c,
	output [3:0]d
);
function [3:0] begin_end;//定义函数名称
    input [3:0] data_in; //定义输入变量
    
        begin
            begin_end[0]=data_in[3];//大小位转换
            begin_end[1]=data_in[2];
            begin_end[2]=data_in[1];
            begin_end[3]=data_in[0];
        end

endfunction
    
    assign c=begin_end(a);//调用函数
    assign d=begin_end(b);

endmodule

猜你喜欢

转载自blog.csdn.net/weixin_46188211/article/details/125702420