(1)设计定义:UART_RX模块接收数据,通过写入逻辑写入RAM存储器中,然后通过读取逻辑,从RAM中读出数据,发送给TFT显示屏。
(2)FPGA逻辑资源有限,因此设置128 * 128 像素点图片输出,首先使用画图工具制造合适的像素图片,保存为24位位图。
(3)Verilog代码编写:

- 串口数据接收模块:
module UART_RX(clk,reset_n,uart_rxd,rx_done,rx_data); input clk; input reset_n; input uart_rxd; output reg rx_done; output reg [7:0]rx_data; reg dff0_uart_rxd; reg dff1_uart_rxd; reg last_dff1_uart_rxd; wire nedge; wire w_rx_done; reg [29:0]baud_cnt; reg [3:0]bit_cnt; reg en_baud_cnt; reg [7:0]r_rx_data; parameter f_system = 50_000_000; parameter Baud = 115200; parameter MCNT = f_system/Baud; //为解决亚稳态问题,加入两个寄存器,使外部输入的异步信号uart_rx与时钟信号clk同步。 //同步化处理 always@(posedge clk) begin dff0_uart_rxd <= uart_rxd; dff1_uart_rxd <= dff0_uart_rxd; end //下降沿设计 always@(posedge clk) last_dff1_uart_rxd <= dff1_uart_rxd; assign nedge = last_dff1_uart_rxd && (!dff1_uart_rxd); //波特计数器模块设计 always@(posedge clk or negedge reset_n) if(!reset_n) baud_cnt <= 30'd0; else if(en_baud_cnt)begin if(baud_cnt == MCNT - 1) baud_cnt <= 30'd0; else baud_cnt <= baud_cnt + 30'd1; end else baud_cnt <= 30'd0; //位设计 always@(posedge clk or negedge reset_n) if(!reset_n) bit_cnt <= 4'd0; else if(w_rx_done) bit_cnt <= 4'd0; else if(baud_cnt == MCNT - 1) bit_cnt <= bit_cnt + 4'd1; else bit_cnt <= bit_cnt; //en_baud_cnt使能信号的设计 always@(posedge clk or negedge reset_n) if(!reset_n) en_baud_cnt <= 0; else if(nedge) en_baud_cnt <= 1; else if((baud_cnt == MCNT/2)&&(bit_cnt == 0)&& (dff1_uart_rxd)) en_baud_cnt <= 0; else if(w_rx_done) en_baud_cnt <= 0; else en_baud_cnt <= en_baud_cnt; //接收主代码设计 always@(posedge clk or negedge reset_n) if(!reset_n) r_rx_data <= 8'd0; else if(baud_cnt == MCNT/2)begin case(bit_cnt) 4'd1:r_rx_data[0] <= dff1_uart_rxd; 4'd2:r_rx_data[1] <= dff1_uart_rxd; 4'd3:r_rx_data[2] <= dff1_uart_rxd; 4'd4:r_rx_data[3] <= dff1_uart_rxd; 4'd5:r_rx_data[4] <= dff1_uart_rxd; 4'd6:r_rx_data[5] <= dff1_uart_rxd; 4'd7:r_rx_data[6] <= dff1_uart_rxd; 4'd8:r_rx_data[7] <= dff1_uart_rxd; default: r_rx_data <= r_rx_data; endcase end else r_rx_data <= r_rx_data; always@(posedge clk) if(w_rx_done) rx_data <= r_rx_data; else rx_data <= rx_data; //w_rx_done 和 rx_done信号的设计 assign w_rx_done = (baud_cnt == MCNT/2)&&(bit_cnt == 9); always@(posedge clk) rx_done <= w_rx_done; endmodule - ram读写逻辑控制模块:
module ram_ctrl( input clk , input reset_n , input clk_33M , input [7:0] rx_data , input rx_done , input [9:0] hang , input [9:0] lie , output reg ram_wren , output reg [13:0] rdaddress , output reg [13:0] ram_wraddr , output [15:0] ram_w_data , output img_display ); //128*128*2 = 32768 需要一个十五位的寄存器去计数 reg [14:0] done_cnt ; reg [15:0] temp_wrdata ; /* ---------------------------------------------------写逻辑部分------------------------------------------------*/ //串口传输完成计数器 always@(posedge clk or negedge reset_n) if(!reset_n) done_cnt <= 15'd0; else if(rx_done) done_cnt <= done_cnt + 15'd1; else done_cnt <= done_cnt; //ram写入数据寄存器 always@(posedge clk or negedge reset_n) if(!reset_n) temp_wrdata <= 16'd0; else if(rx_done) temp_wrdata <= {temp_wrdata[7:0],rx_data}; else temp_wrdata <= temp_wrdata; assign ram_w_data = temp_wrdata ; //ram写使能设计 always@(posedge clk or negedge reset_n) if(!reset_n) ram_wren <= 1'd0; else if(done_cnt[0] && rx_done) ram_wren <= 1'd1; else ram_wren <= 1'd0; //ram写地址设计 always@(posedge clk or negedge reset_n) if(!reset_n) ram_wraddr <= 14'd0; else if(done_cnt[0] && rx_done) ram_wraddr <= done_cnt[14:1]; else ram_wraddr <= ram_wraddr; /* ---------------------------------------------------读逻辑部分------------------------------------------------*/ //tft读出有效区域设计 assign img_display = (hang >= 337) && (hang < 465) && (lie >= 177) && (lie < 305) ; //ram读地址设计 always@(posedge clk_33M or negedge reset_n) if(!reset_n) rdaddress <= 14'd0; else if(img_display) rdaddress <= rdaddress + 14'd1; else rdaddress <= rdaddress; endmodule - 顶层模块:
module tft_img_top( input clk , input reset_n , input uart_rxd , output hsync , output vsync , output [15:0] rgb_tft , output tft_bl , output tft_clk , output tft_DE ); wire rx_done ; wire [7:0] rx_data ; wire clk_33M ; wire locked ; wire [9:0] hang ; wire [9:0] lie ; wire ram_wren ; wire [13:0] rdaddress ; wire [13:0] ram_wraddr ; wire [15:0] data_tft ; wire [15:0] ram_w_data ; wire [15:0] q ; wire [15:0] data_in ; wire img_display ; UART_RX UART_RX_INST( .clk (clk ), .reset_n (locked ), .uart_rxd (uart_rxd ), .rx_done (rx_done ), .rx_data (rx_data ) ); pll_33M pll_33M_inst ( .areset ( ~reset_n ), .inclk0 ( clk ), .c0 ( clk_33M ), .locked ( locked ) ); ram_ctrl ram_ctrl_inst( .clk ( clk ), .reset_n ( locked ), .clk_33M ( clk_33M ), .rx_data ( rx_data ), .rx_done ( rx_done ), .hang ( hang ), .lie ( lie ), .ram_wren (ram_wren ), .rdaddress (rdaddress ), .ram_wraddr (ram_wraddr ), .ram_w_data (ram_w_data ), .img_display (img_display ) ); myram myram_inst ( .data ( ram_w_data ), .rdaddress ( rdaddress ), .rdclock ( clk_33M ), .wraddress ( ram_wraddr ), .wrclock ( clk ), .wren ( ram_wren ), .q ( q ) ); assign data_in = (img_display) ? q : 16'd0 ; tft_ctrl tft_ctrl_inst( .clk_33M (clk_33M ), .reset_n (locked ), .data_in (data_in ), .hang (hang ), .lie (lie ), .hsync (hsync ), .vsync (vsync ), .rgb_tft (rgb_tft ), .tft_bl (tft_bl ), .tft_clk (tft_clk ), .tft_DE (tft_DE ) ); endmodule
(4)引脚绑定:

(5)实验现象:




882

被折叠的 条评论
为什么被折叠?



