最近做了一些公司的笔试题,和牛客网上的题还是很重合的!坚定了我继续刷题的目标!更新2道比较难的题:
目录
信号发生器
方波
锯齿波
三角波
冒泡法排序
信号发生器
文章图片
这道题比较难,想了很久才写出满意的程序。首先,方波的周期是20,锯齿波的周期是21,三角波的周期是40,且wave
的最大值是20。题目没有明确告知,我是从其他人的题解中知道的。下面分别分析一下三种波形如何产生。
方波
方波模式需注意wave
在什么时候翻转。设置一个计数器cnt
,计数范围是0-19。该计数器仅在方波模式也就是wave_choise==0
时工作。
1 2 3 |
wave <= cnt == 9 ? 20 : 【FPGA刷题——信号发生器+冒泡法求6个数中的最小值】
cnt == 19 ? 0 :
wave;
|
cnt
值在0~9时,wave==20
;当cnt
值在10~19时,wave==0
。也就是wave
应在cnt==10
时从0变为20。但由于非阻塞赋值,cnt==10
时,wave
应对cnt==9
是否成立进行判断。cnt==19
也是同样原因。锯齿波
锯齿波比较简单。
wave
产生锯齿波时,需要从0增加到20,所以周期是21。 当wave
增加到20时,清零。 1 |
wave <= wave== 20 ? 0 : wave+ 1 ;
|
三角波模式需要设置一个标志位
flag
。flag
仅在三角波模式也就是wave_chosie==2
时工作。当flag==0
时,wave
减少;当flag==1
时,wave
增加。 1 |
wave <= flag== 0 ? wave- 1 : wave+ 1 ;
|
wave
是下降的,所以flag
的默认值是0。wave
在最小值0和最大值20时,flag
应进行翻转。同样由于是非阻塞赋值,所以wave
上升到19时,flag
从1到0,也就是flag <= wave==19&&flag==1? 0: flag
;wave
下降到1时,flag
从0到1,也就是flag <= wave==1&&flag==0? 1: flag
。完整代码如下:
`timescale 1ns/1ns
module signal_generator(
input clk,
input rst_n,
input [1:0] wave_choise,
output reg [4:0]wave
);
reg [4:0] cnt;
reg flag;
// 方波模式下,计数器控制
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
cnt <= 0;
else
cnt <= wave_choise!=0 ? 0:
cnt==19? 0:
cnt + 1;
end// 三角波模式下,标志位控制
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
flag <= 0;
else
flag <= wave_choise!=2 ? 0:
wave==1 ? 1:
wave==19? 0:
flag;
end// 更新wave信号
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
wave <= 0;
else
case(wave_choise)
0: wave <= cnt == 9? 20:
cnt ==19? 0:
wave;
1: wave <= wave==20? 0: wave+1;
2: wave <= flag==0 ? wave-1: wave+1;
default: wave <= 0;
endcase
end
endmodule
冒泡法排序 求6个数中的最小值,且保证索引值不变,输入输出已经给出,如下:
module MinValue
(
input InClk,
input [7:0]InData0,
input [7:0]InData1,
input [7:0]InData2,
input [7:0]InData3,
input [7:0]InData4,
input [7:0]InData5,
input [7:0]InData6,
output [7:0]OutMinValue,
output [2:0]OutMinIndex);
首先,我们定义6个寄存器,寄存输入的6个数据,由于题目要求索引值不改变,再设置6个寄存器寄存每一个数据的索引值:
reg [7:0] MinValue1;
reg [7:0] MinValue2;
reg [7:0] MinValue3;
reg[7:0]MinValue4;
reg [7:0]MinValue5;
reg[7:0]MinValue6;
reg[2:0]MinIndex1;
reg[2:0]MinIndex2;
reg[2:0]MinIndex3;
reg[2:0]MinIndex4;
reg[2:0]MinIndex5;
reg[2:0]MinIndex6;
根据冒泡排序的原理,如果数据a>数据b,b是目前的最小值,则交换a和b的数值(同时交换a和b的索引值),a就成为了目前的最小值。数据a<数据b,a本身就是目前的最小值,则无需交换。再用a与其他数据进行比较:
always @(posedge InClk ) begin
if (Indata0<=Indata1) begin//数据0小于1
MinValue1<=InData0;
//数据1成原先的数据0
MinIndex1<=3'd0;
//数据1索引变成数据0的
end
elsebegin
MinValue1<=Indata1;
//数据1本来就是最小值,索引不变
MinIndex1<=3'd1;
end
endalways @(posedge InClk ) begin
if (Indata2<=Indata3) begin
MinValue2<=InData2;
MinIndex2<=3'd2;
end
elsebegin
MinValue2<=Indata3;
MinIndex2<=3'd3;
end
endalways @(posedge InClk ) begin
if (Indata4<=Indata5) begin
MinValue3<=InData4;
MinIndex3<=3'd4;
end
elsebegin
MinValue3<=Indata5;
MinIndex3<=3'd5;
end
end
经过上面的操作,(数据0和数据1比较)最小值是数据1,(数据2和数据3比较)最小值是数据1,(数据4和数据5比较)最小值是数据3。
接下来对数据1,2,3进行比较:首先比较数据1和数据2,较小的给数据4,数据3赋给数据5;再比较数据4和数据5,较小的给数据6,至此,数据6就是最小的数据了
always @(posedge InClk ) begin
if (MinValue1<=MinValue2) begin
MinValue4<=MinValue1;
MinIndex4<=MinIndex1;
end
elsebegin
MinValue4<=MinValue2;
MinIndex4<=MinIndex2;
end
endalways @(posedge InClk ) begin
MinValue5<=MinValue3;
MinIndex5<=MinIndex3;
endalways @(posedge InClk ) begin
if (MinValue4<=MinValue5) begin
MinValue6<=MinValue4;
MinIndex6<=MinIndex4;
end
elsebegin
MinValue6<=MinValue5;
MinIndex6<=MinIndex5;
end
endassign OutMinValue = https://www.it610.com/article/MinValue6;
assign OutMinIndex =MinIndex6;
冒泡排序的顺序都是可以自己定义的,不一定非要1~n,只要每次冒泡完成之后将数据值交换+索引交换即可!
推荐阅读
- FPGA时序分析
- FPGA时序约束
- FPGA——时钟分频
- java|FPGA时序约束分享01_约束四大步骤
- FPGA约束方法与技巧|(05)FPGA时序约束三大步骤
- FPGA20个例程|FPGA 20个例程篇(10.遍历DDR3内存颗粒读写循环校验)
- FPGA20个例程|FPGA 20个例程篇(11.USB2.0接收并回复CRC16位校验)
- fpga开发|博客更新计划的说明
- FPGA20个例程|FPGA 20个例程篇(7.FLASH读写断电存储)