• 正文
  • 相关推荐
申请入驻 产业图谱

FPGA相关职位笔/面试题分享(三)

09/28 08:56
642
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

欢迎各位朋友关注“郝旭帅电子设计团队”公众号,本公众号会定时更新相关技术类资料、软件等等,感兴趣的朋友可以浏览一下本公众号的其他“模块”,希望各位朋友都能在本公众号获得一些自己想要的“东西”。

本篇主要讨论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) begin    if (reset == 1'b1)      cnt <= 4'd0;    else      if (trig == 1'b1 && cnt == 4'd0)        cnt <= cnt + 1'b1;      else        if (cnt > 4'd0 && cnt < 4'd9)          cnt <= cnt + 1'b1;        else          cnt <= 4'd0;  end    assign txd = send_buf[0];
  always @ (posedge clk) begin    if (reset == 1'b1)      send_buf <= { 9'd0,1'b1};    else      if (trig == 1'b1 && cnt == 4'd0)         send_buf <= {1'b1, pdata, 1'b0};      else        if (cnt > 4'd0)          send_buf <= send_buf >> 1;        else          send_buf <= send_buf;  end
endmodule 

仿真代码如下:产生随机测试。

注:tb中产生的信号,不要与时钟边沿对齐。发送一包数据帧需要九个周期,在产生数据时,空闲期要大于九个周期。

`timescale 1ns/1ps
module 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 begin    reset = 1'b1;    trig = 1'b0;    pdata = 8'd0;    # 1001    reset = 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;  end
endmodule 

仿真图如下:

通过仿真图可以看出:输出时序与要求一致。

本篇内容中有部分资源来源于网络,如有侵权,请联系作者。

相关推荐