(2条消息) FPGA刷题P1:4选1多路选择器、异步复位的串联T触发器、奇偶校验、移位拼接乘法_居安士的博客-CSDN博客
题目是牛客网的编程题,part1链接在上面,书接上文今天分享part2 !
目录
多功能数据处理器
这一题主要考察的是有符号数的编程,有符号数需要注意以下两点:
(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