欢迎各位朋友关注“郝旭帅电子设计团队”公众号,本公众号会定时更新相关技术类资料、软件等等,感兴趣的朋友可以浏览一下本公众号的其他“模块”,希望各位朋友都能在本公众号获得一些自己想要的“东西”。
本篇主要讨论FPGA相关职位笔/面试题分享(三)
1.??串行数据发送模块实现
请设计基于verilog HDL的程序文件(.v),以及用于仿真的测试(testbench)文件(.v格式)。
A。模块设计(模块名称为:transmitter)
B。输入条件
八位并行信号pdata[7:0]; 时钟信号clk,频率为20MHz; 复位信号reset,规定高电平复位; ?触发信号trig,高脉冲触发。
C。输出时序要求
输出信号txd,空闲时为1,字节起始位为0,数据LSB先行,时序图如下:
解析:考察基本的Verilog 的设计能力,设计输出时序的能力。
设计代码如下:利用移位的方式实现输出。
设计思路:设计一个trig拉高一拍,计数器能够从0到9计数一遍的计数器;在trig时,捕获pdata并且输出起始位;后续九个周期进行不断移位即可(要求为LSB优先,所以输出时选择sendbuf的低位,进行右移即可)。
注:在判断trig时,加上了另外一个条件为cnt等于0,这样可以避免在输出过程中,外面误操作,拉高trig,从而影响当前输出。
module transmitter (input wire clk,input wire reset,input wire trig,input wire [7:0] pdata,output wire txd);reg [9:0] send_buf;reg [3:0] cnt;always @ (posedge clk) beginif (reset == 1'b1)cnt <= 4'd0;elseif (trig == 1'b1 && cnt == 4'd0)cnt <= cnt + 1'b1;elseif (cnt > 4'd0 && cnt < 4'd9)cnt <= cnt + 1'b1;elsecnt <= 4'd0;endassign txd = send_buf[0];always @ (posedge clk) beginif (reset == 1'b1)send_buf <= { 9'd0,1'b1};elseif (trig == 1'b1 && cnt == 4'd0)send_buf <= {1'b1, pdata, 1'b0};elseif (cnt > 4'd0)send_buf <= send_buf >> 1;elsesend_buf <= send_buf;endendmodule
仿真代码如下:产生随机测试。
注:tb中产生的信号,不要与时钟边沿对齐。发送一包数据帧需要九个周期,在产生数据时,空闲期要大于九个周期。
`timescale 1ns/1psmodule transmitter_tb;reg clk;reg reset;reg trig;reg [7:0] pdata;wire txd;transmitter transmitter_inst(.clk (clk ),.reset (reset),.trig (trig ),.pdata (pdata),.txd (txd ));initial clk = 1'b0;always # 25 clk = ~clk;initial beginreset = 1'b1;trig = 1'b0;pdata = 8'd0;# 1001reset = 1'b0;# 1000;repeat (2) begin@ (posedge clk);# 2;trig = 1'b1;pdata = {$random};@ (posedge clk);# 2;trig = 1'b0;repeat (20)@ (posedge clk);end$stop;endendmodule
仿真图如下:
通过仿真图可以看出:输出时序与要求一致。
本篇内容中有部分资源来源于网络,如有侵权,请联系作者。
642