实现上位机与FPGA uart交互

这篇具有很好参考价值的文章主要介绍了实现上位机与FPGA uart交互。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言  初学者学习记录

目的:实现上位机与FPGA uart交互

开发环境:quatus prime 18.1,芯片 altera :EP4CE15F23C8。
实验现象:
1.使用uart:bps=9600(参数可调整),8n1数据结构发送和接收数据。
2.上位机与FPGA 64位数据通讯,16bit head+16地址(最高位0:写;1:读)+32数据。
3.  驱动数据参考下图 《regtable_uartledseg》

fpga ddr3通过串口与上位机通信,FPGA开发,fpga开发

 RTL Viewer:

fpga ddr3通过串口与上位机通信,FPGA开发,fpga开发

说明

1.uart串口接收数据8n1,将接收到的8位数据,串并转换为64位,经过译码器,驱动led和数码管。

2.读取led和数码管时,译码器的64位数据,经并串转换为8位数据,经uart发送。

代码见如下链接。

顶层文件:

module top_cfg_uart_led_seg(
    clk    ,
    rst_n  ,
    rx     ,
    tx     ,
    led    ,
    seg_sel,
    segment
);

input            clk    ;
input            rst_n  ;
input            rx     ;
output           tx     ;
output[ 3:0]     led    ;
output[ 7:0]     seg_sel;
output[ 7:0]     segment;

`include "../src/cfgctrl/uart_ledseg_wire.v"

wire  [63:0]     cfgCtrl_dout;
wire             cfgCtrl_dout_vld;
wire  [63:0]     uart_dout;
wire             uart_dout_vld;

top_uart_cfg u_top_uart_cfg(
    .clk        (clk            ),
    .rst_n      (rst_n          ),
    .rx         (rx             ),
    .cfg_head   (16'h55d5       ),
    .din        (cfgCtrl_dout   ),
    .din_vld    (cfgCtrl_dout_vld),
    .dout       (uart_dout      ),
    .dout_vld   (uart_dout_vld  ),
    .tx         (tx             )
);

cfgctrl u_cfgctrl(
    `include "../src/cfgctrl/uart_ledseg_inst.v"
    .clk         (clk           ),
    .rst_n       (rst_n         ),
    .din         (uart_dout     ),
    .din_vld     (uart_dout_vld ),
    .dout        (cfgCtrl_dout  ),
    .dout_vld    (cfgCtrl_dout_vld)
);



ledctrl u_ledctrl(
    .clk        (clk    ),
    .rst_n      (rst_n  ),
    .led_in     (LED_CTRL_data),
    .led_out    (led    )
);

segdisp#(.SEG_NUM(8)) u_segdisp(
    .clk        (clk    ),
    .rst_n      (rst_n  ),
    .din        ({SEG_CTRL1_d7,SEG_CTRL1_d6,
                  SEG_CTRL1_d5,SEG_CTRL1_d4,
                  SEG_CTRL1_d3,SEG_CTRL1_d2,
                  SEG_CTRL1_d1,SEG_CTRL1_d0}    ),
    .din_vld    (8'hff  ),
    .disp_en    (SEG_CTRL0_en),
    .seg_sel    (seg_sel),
    .segment    (segment)
);  

endmodule

 uart顶层文件:

module top_uart_cfg(
    clk     ,
    rst_n   ,
    rx      ,
    cfg_head,
    din     ,
    din_vld ,
    dout    ,
    dout_vld,
    tx      
);

parameter   BPS     = 5208  ;

input           clk         ; 
input           rst_n       ;
input           rx          ;
input [15:0]    cfg_head    ;
input [63:0]    din         ;
input           din_vld     ;
output[63:0]    dout        ;
output          dout_vld    ;
output          tx          ;

wire  [7:0]         uart_rx_out     ;
wire                uart_rx_out_vld ;
wire  [7:0]         uart_tx_in      ;
wire                uart_tx_in_vld  ;
wire                uart_tx_rdy     ;
wire                uart_cfg_p2s_din_rdy;

uart_rx#(.BPS(BPS))  uart_rx(
                 .clk     (clk              ),
                 .rst_n   (rst_n            ),
                 .din     (rx               ),
                 .dout    (uart_rx_out      ),
                 .dout_vld(uart_rx_out_vld  )
             );

uart_cfg_s2p uart_cfg_s2p(
                .clk        (clk            ),
                .rst_n      (rst_n          ),
                .cfg_head   (cfg_head       ),
                .din        (uart_rx_out    ),
                .din_vld    (uart_rx_out_vld),
                .dout       (dout           ),
                .dout_vld   (dout_vld       )

);


uart_cfg_p2s uart_cfg_p2s(
                .clk        (clk            ),
                .rst_n      (rst_n          ),
                .din        (din            ),
                .din_vld    (din_vld        ),
                .dout_rdy   (uart_tx_rdy    ), 
                .dout       (uart_tx_in     ),
                .dout_vld   (uart_tx_in_vld ),
                .din_rdy    (uart_cfg_p2s_din_rdy)
);

uart_tx#(.BPS(BPS))  uart_tx(
                 .clk     (clk              ),
                 .rst_n   (rst_n            ),
                 .din     (uart_tx_in       ),
                 .din_vld (uart_tx_in_vld   ),
                 .rdy     (uart_tx_rdy      ),
                 .dout    (tx               )
             );



endmodule

 uart并串转换:

module uart_cfg_p2s(
    clk        ,
    rst_n      ,
    din        ,
    din_vld    ,
    din_rdy    , 
    dout       ,
    dout_vld   ,
    dout_rdy    
);

parameter           DIN_W  = 64;
parameter           DOUT_W = 8  ;
parameter           C_NUM  = 8  ;

input               clk         ;
input               rst_n       ;
input [ DIN_W-1:0]  din         ;
input               din_vld     ;
output              din_rdy     ;
output[DOUT_W-1:0]  dout        ;
output              dout_vld    ;
input               dout_rdy    ;

wire                flag_add_start;
reg                 flag_add    ;
reg   [ DIN_W-1:0]  din_ff      ;
reg   [ 3:0]        cnt0        ;
wire                add_cnt0    ;
wire                end_cnt0    ;
reg   [DOUT_W-1:0]  dout        ;
reg                 dout_vld    ;
reg                 din_rdy     ;

//reg
assign flag_add_start = flag_add == 0 && din_vld;

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        flag_add <= 0;
    end
    else if(flag_add_start) begin
        flag_add <= 1;
    end
    else if(end_cnt0) begin
        flag_add <= 0;
    end
end

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        din_ff <= 0;
    end
    else if(flag_add_start) begin
        din_ff <= din;
    end
end


always @(posedge clk or negedge rst_n) begin 
    if (rst_n==0) begin
        cnt0 <= 0; 
    end
    else if(add_cnt0) begin
        if(end_cnt0)
            cnt0 <= 0; 
        else
            cnt0 <= cnt0+1 ;
   end
end
assign add_cnt0 = (flag_add && dout_rdy);
assign end_cnt0 = add_cnt0  && cnt0 == (C_NUM)-1 ;

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        dout <= 0;
    end
    else if(add_cnt0) begin
        dout <= din_ff[DIN_W-1-cnt0*DOUT_W-:8];
    end
end

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        dout_vld <= 0;
    end
    else begin
        dout_vld <= add_cnt0;
    end
end

always  @(*)begin
    if(flag_add || din_vld)
        din_rdy = 0;
    else
        din_rdy = 1;        //褰撴澶勭悊鏁版嵁鏃讹紝鍓嶇涓嶈鍙戞暟鎹繃鏉ワ紱

end

endmodule

 uart串并转换: 

module uart_cfg_s2p(
    clk        ,
    rst_n      ,
    cfg_head   ,
    din        ,
    din_vld    ,
    dout       ,
    dout_vld   

);


input               clk        ;              
input               rst_n      ; 
input [ 15:0]       cfg_head   ;
input [  7:0]       din        ;      
input               din_vld    ;      
output[ 63:0]       dout       ;      
output              dout_vld   ;   

wire                flag_head_start;
reg                 flag_head  ;
reg   [  7:0]       din_ff     ;
reg   [  3:0]       cnt0       ;
wire                add_cnt0   ;
wire                end_cnt0   ;
reg   [ 63:0]       dout       ;
reg                 dout_vld   ;


assign flag_head_start = flag_head==0 && (din_ff == cfg_head[15:8] && din == cfg_head[7:0]) && din_vld;

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        flag_head <= 0;
    end
    else if(flag_head_start)begin
        flag_head <= 1;
    end
    else if(end_cnt0)begin
        flag_head <= 0;        
    end
end

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        din_ff <= 0;
    end
    else if(flag_head==0 && din_vld)begin
        din_ff <= din;
    end
    else if(flag_head)begin
        din_ff <= 0;
    end
end



always @(posedge clk or negedge rst_n) begin 
    if (rst_n==0) begin
        cnt0 <= 0; 
    end
    else if(add_cnt0) begin
        if(end_cnt0)
            cnt0 <= 0; 
        else
            cnt0 <= cnt0+1 ;
   end
end
assign add_cnt0 = (flag_head && din_vld);
assign end_cnt0 = add_cnt0  && cnt0 == (6)-1 ;


always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        dout <= 0;
    end
    else if(add_cnt0)begin
        dout[63:48]          <= cfg_head;
        dout[(47)-cnt0*8-:8] <= din;
    end

end

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        dout_vld <= 0;
    end
    else begin
        dout_vld <= end_cnt0;
    end
end


endmodule

 译码

module cfgctrl(
    clk         ,
    rst_n       ,
    din         ,
    din_vld     ,
    `include "../src/cfgctrl/uart_ledseg_intf.v"
    dout        ,
    dout_vld    
    );

parameter           D_W = 64        ;

input               clk             ;
input               rst_n           ;
input[D_W-1:0]      din             ;
input               din_vld         ;
output[D_W-1:0]     dout            ;
output              dout_vld        ;
`include            "../src/cfgctrl/uart_ledseg_io.v"

reg[D_W-1:0]        dout            ;
reg                 dout_vld        ;
wire                reg_wr          ;
wire                reg_rd          ;
wire[14:0]          flag_get_addr   ;
wire[31:0]          flag_get_data   ;

`include "../src/cfgctrl/uart_ledseg_always.v"

assign reg_wr        = din[47]==0 && din_vld;
assign reg_rd        = din[47]==1 && din_vld;
assign flag_get_addr = din[46:32];
assign flag_get_data = din[31:0] ;

always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            dout <= 0;
        end
        else if(din_vld)begin
            dout <= {din[63:32],rdata};
        end
end

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        dout_vld <= 0;
    end
    else begin
        dout_vld <= reg_rd;
    end
end



endmodule

 其他uart_rx、uart_tx、led驱动、数码管驱动,译码器生成代码 省略说明。

若维护改变代码,仅变动驱动部分代码,及译码生成文件即可,uart和译码部分电路不需要改动。以下链接为全部代码:

上传明细-CSDN创作中心文章来源地址https://www.toymoban.com/news/detail-623209.html

到了这里,关于实现上位机与FPGA uart交互的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Xilinx FPGA DDR3设计(三)DDR3 IP核详解及读写测试

    引言 :本文我们介绍下Xilinx DDR3 IP核的重要架构、IP核信号管脚定义、读写操作时序、IP核详细配置以及简单的读写测试。 7系列FPGA DDR接口解决方案如图1所示。 图1、7系列FPGA DDR3解决方案 1.1 用户FPGA逻辑(User FPGA Logic) 如图1中①所示,用户FPGA逻辑块是任何需要连接到外部

    2024年02月06日
    浏览(41)
  • 【FPGA】MIG DDR3读写逻辑测试

            笔者在之前通过microblaze软核的方式实现了DDR3芯片的读写测试,当时对于Xilinx MIG DDR控制器的理解还比较肤浅。还是想通过控制用户接口时序的方式来读写DDR,扩展和加深自己对DDR的理解。 MIG IP核配置请看我的前一篇文章 【FPGA测试】Microblaze测试DDR读写_microblaze

    2024年01月22日
    浏览(32)
  • 基于紫光同创 FPGA 的 DDR3 读写实验

    此篇为专栏 《紫光同创FPGA开发笔记》 的第二篇,记录我的学习FPGA的一些开发过程和心得感悟,刚接触FPGA的朋友们可以先去此专栏置顶 《FPGA零基础入门学习路线》来做最基础的扫盲。 本篇内容基于笔者实际开发过程和正点原子资料撰写,将会详细讲解此 FPGA 实验的全流程

    2024年01月20日
    浏览(42)
  • 【Xilinx FPGA】DDR3 MIG IP 仿真

    Memory Interface Generator (MIG 7 Series)是 Xilinx 为 7 系列器件提供的 Memory 控制器 IP,使用该 IP 可以很方便地进行 DDR3 的读写操作。本文主要记录 Xilinx DDR3 MIG IP 的仿真过程,包括 IP 配置和 DDR3 读写仿真两部分内容。 目录 1 MIG IP 配置 2 DDR3 读写仿真         在 Vivado 开发平台 IP C

    2024年02月09日
    浏览(37)
  • 【Quartus FPGA】EMIF DDR3 读写带宽测试

    在通信原理中,通信系统的有效性用带宽来衡量,带宽定义为每秒传输的比特数,单位 b/s,或 bps。在 DDR3 接口的产品设计中,DDR3 读/写带宽是设计者必须考虑的指标。本文主要介绍了 Quartus FPGA 平台 EMIF 参数配置,以及测试 DDR3 读写带宽的过程,FPGA 器件型号是 Cyclone 10 GX

    2024年02月13日
    浏览(32)
  • FPGA入门 —— DDR3(MIG IP 核) 入门

    DDR 简介 DDR=Double Data Rate双倍速率同步动态随机存储器。严格的说DDR应该叫DDR SDRAM,人们习惯称为DDR,其中,SDRAM 是Synchronous Dynamic Random Access Memory的缩写,即同步动态随机存取存储器。而DDR SDRAM是Double Data Rate SDRAM的缩写,是双倍速率同步动态随机存储器的意思。 SDRAM在一个时

    2024年01月16日
    浏览(43)
  • 【Xilinx FPGA】DDR3 MIG 时钟管脚分配

    之前在验证 FPGA 板卡的芯片管脚时,所用的测试工程使用内部 PLL 生成的时钟作为 DDR3 的参考时钟。后来尝试将参考时钟改为外部 100M 晶振时钟,发现 MIG IP 配置工具找不到相应管脚,于是学习并梳理了 Xilinx DDR3 MIG IP 时钟管脚的分配规则,在这里做个记录。   目录 1 MIG 时钟

    2024年02月06日
    浏览(35)
  • FPGA-基于AXI4接口的DDR3读写顶层模块

    AXI4(Advancede Xtensible Interface 4)是一种高性能、高带宽的总线接口协议,用于在系统级芯片设计中连接不同的IP核(Intellectual Property)或模块。它是由ARM公司开发的,被广泛应用于各种SoC(System-on-Chip)设计中。 AXI4接口协议定义了一组规范,用于描述数据传输、地址传输、控

    2024年04月15日
    浏览(42)
  • FPGA中光纤,ddr3,srio数据传输速率、带宽分析

    需求分析:FPGA通过光纤接收数据,将接受的数据写入ddr中,再通过srio将数据传递给dsp。光纤传输的数据量为17万个32bit数据。 光纤速率分析:由于在光纤IP核中设置的速率为3.125G,单位bit。数据位宽为16bit。又由于光纤传输数据会进行8b/10b编码。因此单根光纤本地的传输速率

    2024年02月13日
    浏览(26)
  • 紫光FPGA DDR3 IP使用和注意事项(axi4协议)

    紫光DDR3 IP使用 对于紫光ddr3 IP核的使用需要注意事情。 阅读ddr ip手册: 1、注意:对于写地址通道,axi_awvalid要一直拉高,axi_awready才会拉高。使用的芯片型号时PG2L100H-6FBG676,不同的型号IP核接口和axi的握手协议也不一样(一定要注意),这点要注意,这也给我挖了一个很大的

    2024年04月12日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包