前言 初学者学习记录
目的:实现上位机与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》
RTL Viewer:
说明
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和译码部分电路不需要改动。以下链接为全部代码:文章来源:https://www.toymoban.com/news/detail-623209.html
上传明细-CSDN创作中心文章来源地址https://www.toymoban.com/news/detail-623209.html
到了这里,关于实现上位机与FPGA uart交互的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!