ZYNQ_project:lcd_pic_400x400
在lcd液晶屏上显示400x400像素的图片,
像素信息通过电脑的串口调试助手,发送给fpga,存储在例化的双端口ram中,
在要显示图像区域,读取ram中的像素信息。
模块框图:
时序图:
代码:
module clk_div(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [15:0] lcd_id ,
output reg clk_lcd ,
output wire clk_rx ,
output wire rst_n
);
wire clk_9Mhz ;
wire clk_33Mhz ;
wire clk_50Mhz ;
wire clk_70Mhz ;
wire locked ;
assign rst_n = (sys_rst_n && locked) ;
assign clk_rx = clk_50Mhz ;
always @(*) begin
case (lcd_id)
16'd4324: clk_lcd <= clk_9Mhz ;
16'd7084: clk_lcd <= clk_33Mhz ;
16'd7016: clk_lcd <= clk_50Mhz ;
16'd4384: clk_lcd <= clk_33Mhz ;
16'd1018: clk_lcd <= clk_70Mhz ;
default : clk_lcd <= 1'b0 ;
endcase
end
pll pll_inst(
.clk_in ( sys_clk ) ,
.resetn ( sys_rst_n ) ,
.clk_9Mhz ( clk_9Mhz ) ,
.clk_33Mhz ( clk_33Mhz ) ,
.clk_50Mhz ( clk_50Mhz ) ,
.clk_70Mhz ( clk_70Mhz ) ,
.locked ( locked )
);
endmodule
// 根据传进来的有效图像坐标信息,产生有效的像素数据�?
module lcd_display (
input wire sys_clk , // lcd的时钟,用来读取ram�?数�??
input wire sys_rst_n ,
input wire clk_wr_ram , // 50Mhz,与rx模块相同时钟�?
input wire [10:0] axi_x ,
input wire [10:0] axi_y ,
input wire [7:0] pi_data ,
input wire pi_flag ,
input wire [10:0] H_SYNC ,
input wire [10:0] H_BACK ,
input wire [10:0] H_DISP ,
input wire [10:0] V_SYNC ,
input wire [10:0] V_BACK ,
input wire [10:0] V_DISP ,
output reg [23:0] pix_data
);
localparam BLACK = 24'h000000 , // 黑色
WHITE = 24'hFFFFFF , // 白色
RosyBrown = 24'hBC8F8F , // �?瑰�??
RED = 24'hFF0000 , // 红色
APRICOT = 24'hE69966 , // 杏黄�?
VIOLET = 24'h8B00FF , // �?罗兰�?
LINEN = 24'hFAF0E6 , // 亚麻�?
KHAKI = 24'h996B1F , // 卡其�?
PEACH = 24'hFFE5B4 , // 桃色
GOLDEN = 24'hFFD700 , // 金色
SkyBule = 24'h87CEEB ; // 天空�?
localparam PIC_SIZE = 11'd400 , // 正方形图片像素大�?100*100
H_BYOND = 11'd200 ,
V_BYOND = 11'd40 ;
localparam DEEP = 18'd160_000 ; // ram深度
// reg signal define
reg [ 7:0] data1 ;
reg [ 7:0] data2 ;
reg [ 7:0] data3 ;
reg [ 1:0] cnt_data ;
reg data_flag ;
reg [17:0] wr_addr ;
reg [23:0] wr_data ;
reg wr_en ;
reg [17:0] rd_addr ;
// wire signal define
wire wr_en_r ;
wire [17:0] wr_addr_r ;
wire [23:0] wr_data_r ;
wire [17:0] rd_addr_r ;
wire all_en ;
wire rd_en ;
wire [23:0] rd_data ;
/******************************************************************************************
********************************************main code**************************************
*******************************************************************************************/
// // reg signal define
// reg [ 7:0] data1 ;
always @(posedge clk_wr_ram or negedge sys_rst_n) begin
if(~sys_rst_n)
data1 <= 8'd0 ;
else if(pi_flag && (cnt_data == 0))
data1 <= pi_data ;
else
data1 <= data1 ;
end
// reg [ 7:0] data2 ;
always @(posedge clk_wr_ram or negedge sys_rst_n) begin
if(~sys_rst_n)
data2 <= 8'd0 ;
else if(pi_flag && (cnt_data == 1))
data2 <= pi_data ;
else
data2 <= data2 ;
end
// reg [ 7:0] data3 ;
always @(posedge clk_wr_ram or negedge sys_rst_n) begin
if(~sys_rst_n)
data3 <= 8'd0 ;
else if(pi_flag && (cnt_data == 2))
data3 <= pi_data ;
else
data3 <= data3 ;
end
// reg [ 1:0] cnt_data ;
always @(posedge clk_wr_ram or negedge sys_rst_n) begin
if(~sys_rst_n)
cnt_data <= 2'd0 ;
else if(pi_flag && cnt_data == 2)
cnt_data <= 2'd0 ;
else if(pi_flag)
cnt_data <= cnt_data + 1'b1 ;
else
cnt_data <= cnt_data ;
end
// reg data_flag ;
always @(posedge clk_wr_ram or negedge sys_rst_n) begin
if(~sys_rst_n)
data_flag <= 1'b0 ;
else if(pi_flag && cnt_data == 2)
data_flag <= 1'b1 ;
else
data_flag <= 1'b0 ;
end
// reg [17:0] wr_addr ;
always @(posedge clk_wr_ram or negedge sys_rst_n) begin
if(~sys_rst_n)
wr_addr <= 18'd0 ;
else if(wr_en &&( wr_addr == DEEP - 1))
wr_addr <= 18'd0 ;
else if(wr_en)
wr_addr <= wr_addr + 1'b1 ;
else
wr_addr <= wr_addr ;
end
// reg [23:0] wr_data ;
always @(posedge clk_wr_ram or negedge sys_rst_n) begin
if(~sys_rst_n)
wr_data <= 24'd0 ;
else if(data_flag)
wr_data <= {data1,data2,data3} ;
else
wr_data <= wr_data ;
end
// reg wr_en ;
always @(posedge clk_wr_ram or negedge sys_rst_n) begin
if(~sys_rst_n)
wr_en <= 1'b0 ;
else
wr_en <= data_flag ;
end
// reg [17:0] rd_addr ; // 读地�?的时钟与lcd的时钟相同�??
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n)
rd_addr <= 18'd0 ;
else if(rd_en && rd_addr == DEEP - 1)
rd_addr <= 18'd0 ;
else if(rd_en)
rd_addr <= rd_addr + 1'b1 ;
else
rd_addr <= rd_addr ;
end
// wire signal define
// wire wr_en_r ;
assign wr_en_r = wr_en ;
// wire [13:0] wr_addr_r ;
assign wr_addr_r = wr_addr ;
// wire [23:0] wr_data_r ;
assign wr_data_r = wr_data ;
// wire [13:0] rd_addr_r ;
assign rd_addr_r = rd_addr ;
// wire all_en ;
assign all_en = 1'b1 ;
// wire rd_en ;
assign rd_en = ((axi_y >= V_SYNC + V_BACK + V_BYOND) && (axi_y <= V_SYNC + V_BACK + V_BYOND + PIC_SIZE - 1)
&& (axi_x >= H_SYNC + H_BACK + H_BYOND) && (axi_x <= H_SYNC + H_BACK + H_BYOND + PIC_SIZE - 1)) ? 1'b1 : 1'b0 ;
// wire [23:0] rd_data ;
// output pix_data
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n)
pix_data <= BLACK ;
else if((axi_y >= V_SYNC + V_BACK) && (axi_y <= V_SYNC + V_BACK + V_DISP - 1)) begin// 在场同�?�有效区间�??
if(rd_en) begin
pix_data <= rd_data ;
end
else begin
if((axi_x >= H_SYNC + H_BACK) && (axi_x <= H_SYNC + H_BACK + H_DISP/10 - 1))
pix_data <= WHITE ;
else
if((axi_x >= H_SYNC + H_BACK + H_DISP/10) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*2 - 1))
pix_data <= BLACK ;
else
if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*2) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*3 - 1))
pix_data <= RosyBrown ;
else
if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*3) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*4 - 1))
pix_data <= APRICOT ;
else
if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*4) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*5 - 1))
pix_data <= RED ;
else
if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*5) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*6 - 1))
pix_data <= VIOLET ;
else
if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*6) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*7 - 1))
pix_data <= KHAKI ;
else
if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*7) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*8 - 1))
pix_data <= PEACH ;
else
if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*8) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*9 - 1))
pix_data <= GOLDEN ;
else
if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*9) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*10 - 1))
pix_data <= SkyBule ;
else
pix_data <= BLACK ;
end
end
else
pix_data <= BLACK ;
end
// 例化ram
ram_24x400x400 ram_24x400x400_inst (
.clka ( clk_wr_ram ) , // input wire clka
.ena ( all_en ) , // input wire ena
.wea ( wr_en_r ) , // input wire [0 : 0] wea
.addra ( wr_addr_r ) , // input wire [13 : 0] addra
.dina ( wr_data_r ) , // input wire [23 : 0] dina
.clkb ( sys_clk ) , // input wire clkb
.enb ( rd_en ) , // input wire enb
.addrb ( rd_addr ) , // input wire [13 : 0] addrb
.doutb ( rd_data ) // output wire [23 : 0] doutb
);
// ila_0 your_instance_name (
// .clk(clk_wr_ram), // input wire clk
// .probe0(pi_flag), // input wire [0:0] probe0
// .probe1(pi_data), // input wire [7:0] probe1
// .probe2(data1), // input wire [6:0] probe2
// .probe3(data2), // input wire [6:0] probe3
// .probe4(data3), // input wire [6:0] probe4
// .probe5(wr_en_r), // input wire [0:0] probe5
// .probe6(wr_addr_r), // input wire [22:0] probe6
// .probe7(wr_addr_r) // input wire [13:0] probe7
// );
// ila_0 ila_0_inst (
// .clk(clk_wr_ram), // input wire clk
// // .probe0(rd_en), // input wire [0:0] probe0
// // .probe1(rd_addr), // input wire [13:0] probe1
// // .probe2(rd_data), // input wire [23:0] probe2
// // .probe3(wr_en_r), // input wire [0:0] probe3
// // .probe4(axi_x), // input wire [10:0] probe4
// // .probe5(axi_y), // input wire [10:0] probe5
// .probe0( ), // input wire [0:0] probe0
// .probe1( ), // input wire [13:0] probe1
// .probe2( ), // input wire [23:0] probe2
// .probe3( ), // input wire [0:0] probe3
// .probe4( ), // input wire [10:0] probe4
// .probe5( ), // input wire [10:0] probe5
// .probe6(pi_flag), // input wire [0:0] probe6
// .probe7(pi_data), // input wire [7:0] probe7
// .probe8 (data1), // input wire [7:0] probe8
// .probe9 (data2), // input wire [7:0] probe9
// .probe10(data3), // input wire [7:0] probe10
// .probe11(wr_data), // input wire [23:0] probe11
// .probe12(cnt_data) // input wire [1:0] probe12
// );
endmodule
// 接口模块,产生接口时序。又名驱动模块。
// 产生像素信息,有效信号。其余信号直接赋值1
module lcd_driver (
input wire sys_clk ,
input wire sys_rst_n ,
input wire [23:0] pix_data ,
input wire [15:0] lcd_id ,
output wire [10:0] H_SYNCtoDIS ,
output wire [10:0] H_BACKtoDIS ,
output wire [10:0] H_DISPtoDIS ,
output wire [10:0] V_SYNCtoDIS ,
output wire [10:0] V_BACKtoDIS ,
output wire [10:0] V_DISPtoDIS ,
output reg lcd_de ,
output wire [23:0] lcd_rgb_out ,
output wire lcd_bl ,
output wire lcd_rstn ,
output wire lcd_hsync ,
output wire lcd_vsync ,
output wire lcd_clk ,
output wire [10:0] axi_x ,
output wire [10:0] axi_y
);
// localparam
// 4.3' 480*272
localparam H_SYNC_4342 = 11'd41 ,
H_BACK_4342 = 11'd2 ,
H_DISP_4342 = 11'd480 ,
H_FRONT_4342 = 11'd2 ,
H_TOTAL_4342 = 11'd525 ,
V_SYNC_4342 = 11'd10 ,
V_BACK_4342 = 11'd2 ,
V_DISP_4342 = 11'd272 ,
V_FRONT_4342 = 11'd2 ,
V_TOTAL_4342 = 11'd286 ,
// 7' 800*480
H_SYNC_7084 = 11'd128 ,
H_BACK_7084 = 11'd88 ,
H_DISP_7084 = 11'd800 ,
H_FRONT_7084 = 11'd40 ,
H_TOTAL_7084 = 11'd1056 ,
V_SYNC_7084 = 11'd2 ,
V_BACK_7084 = 11'd33 ,
V_DISP_7084 = 11'd480 ,
V_FRONT_7084 = 11'd10 ,
V_TOTAL_7084 = 11'd525 ,
// 7' 1024*600
H_SYNC_7016 = 11'd20 ,
H_BACK_7016 = 11'd140 ,
H_DISP_7016 = 11'd1024 ,
H_FRONT_7016 = 11'd160 ,
H_TOTAL_7016 = 11'd1344 ,
V_SYNC_7016 = 11'd3 ,
V_BACK_7016 = 11'd20 ,
V_DISP_7016 = 11'd600 ,
V_FRONT_7016 = 11'd12 ,
V_TOTAL_7016 = 11'd635 ,
// 10.1' 1280*800
H_SYNC_1018 = 11'd10 ,
H_BACK_1018 = 11'd80 ,
H_DISP_1018 = 11'd1280 ,
H_FRONT_1018 = 11'd70 ,
H_TOTAL_1018 = 11'd1440 ,
V_SYNC_1018 = 11'd3 ,
V_BACK_1018 = 11'd10 ,
V_DISP_1018 = 11'd800 ,
V_FRONT_1018 = 11'd10 ,
V_TOTAL_1018 = 11'd823 ,
// 4.3' 800*480
H_SYNC_4384 = 11'd128 ,
H_BACK_4384 = 11'd88 ,
H_DISP_4384 = 11'd800 ,
H_FRONT_4384 = 11'd40 ,
H_TOTAL_4384 = 11'd1056 ,
V_SYNC_4384 = 11'd2 ,
V_BACK_4384 = 11'd33 ,
V_DISP_4384 = 11'd480 ,
V_FRONT_4384 = 11'd10 ,
V_TOTAL_4384 = 11'd525 ;
// 不同分辨率时序参数不同
reg [10:0] H_SYNC ;
reg [10:0] H_BACK ;
reg [10:0] H_DISP ;
reg [10:0] H_FRONT ;
reg [10:0] H_TOTAL ;
reg [10:0] V_SYNC ;
reg [10:0] V_BACK ;
reg [10:0] V_DISP ;
reg [10:0] V_FRONT ;
reg [10:0] V_TOTAL ;
// reg signal define
reg [10:0] cnt_row ; // 行计数器,记录一行中的第几列。行计数器归零,说明一行扫描完。
reg [10:0] cnt_col ; // 列计数器,记录一列中的第几行。列计数器归零,说明一帧图像扫描完。
// wire signal define
wire valid_H ; // 行时序有效信号
wire valid_V ; // 列时序有效信号
wire valid_HV; // 图像有效信号,由于lcd_display模块中产生像素数据信息是时序逻辑,所以lcd_de信号要对图像有效信号打1拍。
/******************************************************************************************
********************************************main code**************************************
*******************************************************************************************/
// 时序参数赋值
always @(*) begin
case(lcd_id)
16'd4324: begin
H_SYNC = H_SYNC_4342 ;
H_BACK = H_BACK_4342 ;
H_DISP = H_DISP_4342 ;
H_FRONT = H_FRONT_4342 ;
H_TOTAL = H_TOTAL_4342 ;
V_SYNC = V_SYNC_4342 ;
V_BACK = V_BACK_4342 ;
V_DISP = V_DISP_4342 ;
V_FRONT = V_FRONT_4342 ;
V_TOTAL = V_TOTAL_4342 ;
end
16'd7084: begin
H_SYNC = H_SYNC_7084 ;
H_BACK = H_BACK_7084 ;
H_DISP = H_DISP_7084 ;
H_FRONT = H_FRONT_7084 ;
H_TOTAL = H_TOTAL_7084 ;
V_SYNC = V_SYNC_7084 ;
V_BACK = V_BACK_7084 ;
V_DISP = V_DISP_7084 ;
V_FRONT = V_FRONT_7084 ;
V_TOTAL = V_TOTAL_7084 ;
end
16'd7016: begin
H_SYNC = H_SYNC_7016 ;
H_BACK = H_BACK_7016 ;
H_DISP = H_DISP_7016 ;
H_FRONT = H_FRONT_7016 ;
H_TOTAL = H_TOTAL_7016 ;
V_SYNC = V_SYNC_7016 ;
V_BACK = V_BACK_7016 ;
V_DISP = V_DISP_7016 ;
V_FRONT = V_FRONT_7016 ;
V_TOTAL = V_TOTAL_7016 ;
end
16'd4384: begin
H_SYNC = H_SYNC_4384 ;
H_BACK = H_BACK_4384 ;
H_DISP = H_DISP_4384 ;
H_FRONT = H_FRONT_4384 ;
H_TOTAL = H_TOTAL_4384 ;
V_SYNC = V_SYNC_4384 ;
V_BACK = V_BACK_4384 ;
V_DISP = V_DISP_4384 ;
V_FRONT = V_FRONT_4384 ;
V_TOTAL = V_TOTAL_4384 ;
end
16'd1018: begin
H_SYNC = H_SYNC_1018 ;
H_BACK = H_BACK_1018 ;
H_DISP = H_DISP_1018 ;
H_FRONT = H_FRONT_1018 ;
H_TOTAL = H_TOTAL_1018 ;
V_SYNC = V_SYNC_1018 ;
V_BACK = V_BACK_1018 ;
V_DISP = V_DISP_1018 ;
V_FRONT = V_FRONT_1018 ;
V_TOTAL = V_TOTAL_1018 ;
end
default : begin
H_SYNC = H_SYNC_1018 ;
H_BACK = H_BACK_1018 ;
H_DISP = H_DISP_1018 ;
H_FRONT = H_FRONT_1018 ;
H_TOTAL = H_TOTAL_1018 ;
V_SYNC = V_SYNC_1018 ;
V_BACK = V_BACK_1018 ;
V_DISP = V_DISP_1018 ;
V_FRONT = V_FRONT_1018 ;
V_TOTAL = V_TOTAL_1018 ;
end
endcase
end
// // reg signal define
// reg [10:0] cnt_row ; // 行计数器,记录一行中的第几列。行计数器归零,说明一行扫描完。
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n)
cnt_row <= 11'd0 ;
else if(cnt_row == (H_TOTAL - 1))
cnt_row <= 11'd0 ;
else
cnt_row <= cnt_row + 1'b1 ;
end
// reg [10:0] cnt_col ; // 列计数器,记录一列中的第几行。列计数器归零,说明一帧图像扫描完。
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n)
cnt_col <= 11'd0 ;
else if((cnt_col == (V_TOTAL - 1)) && (cnt_row == (H_TOTAL - 1)))
cnt_col <= 11'd0 ;
else if(cnt_row == (H_TOTAL - 1))
cnt_col <= cnt_col + 1'b1 ;
else
cnt_col <= cnt_col ;
end
// // wire signal define
// wire valid_H ; // 行时序有效信号
assign valid_H = ((cnt_row >= H_SYNC + H_BACK) && (cnt_row <= H_SYNC + H_BACK + H_DISP - 1)) ? 1'b1 : 1'b0 ;
// wire valid_V ; // 列时序有效信号
assign valid_V = ((cnt_col >= V_SYNC + V_BACK) && (cnt_col <= V_SYNC + V_BACK + V_DISP - 1)) ? 1'b1 : 1'b0 ;
// wire valid_HV; // 图像有效信号,由于lcd_display模块中产生像素数据信息是时序逻辑,所以lcd_de信号要对图像有效信号打1拍。
assign valid_HV = (valid_H && valid_V) ;
// output wire [10:0] axi_x ,
assign axi_x = (valid_HV) ? cnt_row : 11'd0 ;
// output wire [10:0] axi_y ,
assign axi_y = (valid_HV) ? cnt_col : 11'd0 ;
// output wire [23:0] lcd_rgb_out ,
assign lcd_rgb_out = pix_data ;
// output reg lcd_de ,
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n)
lcd_de <= 1'b0 ;
else
lcd_de <= valid_HV ;
end
// 本实验没用到的信号,赋值1;
assign lcd_bl = 1'b1 ;
assign lcd_rstn = 1'b1 ;
assign lcd_hsync = 1'b1 ;
assign lcd_vsync = 1'b1 ;
assign lcd_clk = (sys_rst_n == 1'b1) ? sys_clk : 1'b0 ;
// 传给像素数据生成模块的时序参数
assign H_SYNCtoDIS = H_SYNC ;
assign H_BACKtoDIS = H_BACK ;
assign H_DISPtoDIS = H_DISP ;
assign V_SYNCtoDIS = V_SYNC ;
assign V_BACKtoDIS = V_BACK ;
assign V_DISPtoDIS = V_DISP ;
endmodule
`define CLOCK 50_000_00//0
`define BPS 115200
`define BIT_NO_CHACK 9 // 1bit起始位+8bit数据位
`define BIT_CHACK 10 // 1bit起始位+8bit数据位+1bit校验位
`define ODD 1 // 1bit起始位+8bit数据位+1bit校验位
`define EVEN 0 // 1bit起始位+8bit数据位+1bit校验位
/*
奇校验:原始码流+校验位 总共有奇数个1
偶校验:原始码流+校验位 总共有偶数个1
*/
/*
// 24'h000000 4324 9Mhz 480*272
// 24'h800000 7084 33Mhz 800*480
// 24'h008080 7016 50Mhz 1024*600
// 24'h000080 4384 33Mhz 800*480
// 24'h800080 1018 70Mhz 1280*800
*/
module rd_id(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [23:0] lcd_rgb ,
output reg [15:0] lcd_id
);
reg rd_flag ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n)
rd_flag <= 1'b1 ;
else
rd_flag <= 1'b0 ;
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n)
lcd_id <= 24'd0 ;
else if(rd_flag) begin
case (lcd_rgb)
24'h000000: lcd_id <= 16'd4324 ;
24'h800000: lcd_id <= 16'd7084 ;
24'h008080: lcd_id <= 16'd7016 ;
24'h000080: lcd_id <= 16'd4384 ;
24'h800080: lcd_id <= 16'd1018 ;
default : lcd_id <= 16'd1018 ;
endcase
end
end
endmodule
// // uart�Ľ���ģ�飬Ҫ�����ʿɵ�,�ػ�ʵ��
// // ��ɻػ�ʵ������У��λ
// // Ȼ�����led��������Ŀ���ģ��
// `include "para.v"
// module rx (
// input wire sys_clk ,
// input wire sys_rst_n ,
// input wire rx ,
// output reg [7:0] po_data , // port_output
// output reg po_flag
// );
// // parameter
// parameter MAX_BPS_CNT = `CLOCK/`BPS ,//434 ,
// MAX_BIT_CNT = `BIT_CHACK ;//10 ;
// localparam RX_MOD = 1'b1 ,
// CHECK_MOD = `EVEN ;
// // reg signal define
// reg rx_r1 ;
// reg rx_r2 ;
// reg [31:0] cnt_bps ;
// reg work ;
// reg [3:0] cnt_bit ;
// reg [7:0] data_reg ;
// reg check ;
// reg check_reg;
// // wire signal define
// wire nege ;
// /*******************************************************************/
// // // reg signal define
// // reg rx_r1 ;
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n)
// rx_r1 <= 1'b1 ;
// else
// rx_r1 <= rx ;
// end
// // reg rx_r2 ;
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n)
// rx_r2 <= 1'b1 ;
// else
// rx_r2 <= rx_r1 ;
// end
// // reg work ;
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n)
// work <= 1'b0 ;
// else if(nege)
// work <= 1'b1 ;
// else if((cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT - 1))) // ��������������end_cnt_XXX�����棬�������
// work <= 1'b0 ;
// else
// work <= work ;
// end
// // reg [31:0] cnt_bps ;
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n)
// cnt_bps <= 32'd0 ;
// else if(work && (cnt_bps == (MAX_BPS_CNT - 1)))
// cnt_bps <= 32'd0 ;
// else if(work)
// cnt_bps <= cnt_bps + 1'b1 ;
// else
// cnt_bps <= 32'd0 ;
// end
// // reg [3:0] cnt_bit ; Ӧ�û��0
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n)
// cnt_bit <= 4'd0 ;
// else if (work && (cnt_bps == (MAX_BPS_CNT - 1) && cnt_bit == (MAX_BIT_CNT - 1)))
// cnt_bit <= 4'd0 ;
// else if (work && (cnt_bps == (MAX_BPS_CNT - 1)))
// cnt_bit <= cnt_bit + 1'b1 ;
// else if(work)
// cnt_bit <= cnt_bit ;
// else
// cnt_bit <= 8'd0 ;
// end
// // reg [7:0] data_reg;
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n)
// data_reg <= 8'd0 ;
// else if(work && cnt_bps == (MAX_BPS_CNT/2)) begin // �������ɼ����ݵ�ʱ��
// case (cnt_bit)
// 0 : data_reg <= 8'd0 ;
// 1 : data_reg[cnt_bit - 1] <= rx_r2 ;
// 2 : data_reg[cnt_bit - 1] <= rx_r2 ;
// 3 : data_reg[cnt_bit - 1] <= rx_r2 ;
// 4 : data_reg[cnt_bit - 1] <= rx_r2 ;
// 5 : data_reg[cnt_bit - 1] <= rx_r2 ;
// 6 : data_reg[cnt_bit - 1] <= rx_r2 ;
// 7 : data_reg[cnt_bit - 1] <= rx_r2 ;
// 8 : data_reg[cnt_bit - 1] <= rx_r2 ;
// default: data_reg <= data_reg ;
// endcase
// end else
// data_reg <= data_reg ;
// end
// // // wire signal define
// // wire nege ;
// assign nege = ~rx_r1 && rx_r2 ;
// // reg check ;
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n)
// check <= 1'b0 ;
// else if(CHECK_MOD && (cnt_bit == ((MAX_BIT_CNT - 2))) && (cnt_bps == (MAX_BPS_CNT - 1)))
// check <= ~^data_reg ;
// else if(~CHECK_MOD && (cnt_bit == ((MAX_BIT_CNT - 2))) && (cnt_bps == (MAX_BPS_CNT - 1)))
// check <= ^data_reg ;
// else
// check <= check ;
// end
// // reg check_reg;
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n)
// check_reg <= 1'b0 ;
// else if((cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT /2)))
// check_reg <= rx_r2 ;
// else
// check_reg <= check_reg ;
// end
// // output reg [7:0] po_data , // port_output
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n)
// po_data <= 8'd0 ;
// else if((check == check_reg) && (cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT - 1)))
// po_data <= data_reg ;
// else if(RX_MOD)
// po_data <= po_data ;
// else
// po_data <= 8'd0 ;
// end
// // output reg po_flag
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n)
// po_flag <= 1'd0 ;
// else if((check == check_reg) && ((cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT - 1))))
// po_flag <= 1'b1 ;
// else
// po_flag <= 1'd0 ;
// end
// endmodule
module rx
#(
parameter UART_BPS = 'd115200 ,
CLK_FREQ = 'd50_000_000
)(
input wire sys_clk ,
input wire sys_rst_n ,
input wire rx ,
output reg [7:0] po_data ,
output reg po_flag
);
localparam BAUD_CNT_MAX = CLK_FREQ / UART_BPS ;
// reg define signal
reg rx_reg1 ;
reg rx_reg2 ;
reg rx_reg3 ;
reg start ;
reg work_en ;
reg [12:00] baud_cnt ;
reg bit_flag ;
reg [ 3: 0] bit_cnt ;
reg [ 7: 0] rx_data ;
reg rx_flag ;
// rx_reg1 ;rx_reg2 ;rx_reg3 ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
rx_reg1 <= 1'b1 ;
rx_reg2 <= 1'b1 ;
rx_reg3 <= 1'b1 ;
end else begin
rx_reg1 <= rx ;
rx_reg2 <= rx_reg1 ;
rx_reg3 <= rx_reg2 ;
end
end
// start ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
start <= 1'b0 ;
end else begin
if(rx_reg3 == 1'b1 && rx_reg2 == 1'b0 && bit_cnt == 4'd0) begin // 或者bit_cnt换成 work_en == 0
start <= 1'b1 ;
end else begin
start <= 1'b0 ;
end
end
end
// work_en ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
work_en <= 1'b0 ;
end else begin
if(start == 1'b1) begin
work_en <= 1'b1 ;
end else begin
if((bit_cnt == 4'd8) && (bit_flag == 1'b1)) begin
work_en <= 1'b0 ;
end else begin
work_en <= work_en ;
end
end
end
end
// [12:00] baud_cnt ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
baud_cnt <= 13'd0 ;
end else begin
if(work_en == 1'b1 && baud_cnt == BAUD_CNT_MAX - 1'b1) begin
baud_cnt <= 13'd0 ;
end else begin
if(work_en == 1'b1) begin
baud_cnt <= baud_cnt + 1'b1 ;
end else begin
baud_cnt <= 13'd0 ;
end
end
end
end
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n) begin
// baud_cnt <= 13'd0 ;
// end else begin
// if(work_en == 1'b1 && baud_cnt == BAUD_CNT_MAX - 1'b1 || work_en == 1'b0) begin
// baud_cnt <= 13'd0 ;
// end else begin
// baud_cnt <= baud_cnt + 1'b1 ;
// end
// end
// end
// bit_flag ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
bit_flag <= 1'b0 ;
end else begin
if(baud_cnt == BAUD_CNT_MAX - 1'b1) begin // 也可以写成baud_cnt == BAUD_CNT_MAX / 2 - 1'b1
bit_flag <= 1'b1 ; // 这样后面赋值时,就可以直接用bit_flag .
end else begin
bit_flag <= 1'b0 ;
end
end
end
// [ 2: 0] bit_cnt ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
bit_cnt <= 4'd0 ;
end else begin
if(bit_flag == 1'b1 && work_en == 1'b1 && bit_cnt == 4'd8) begin
bit_cnt <= 4'd0 ;
end else begin
if(bit_flag == 1'b1 && work_en == 1'b1) begin
bit_cnt <= bit_cnt + 1'b1 ;
end else begin
if(work_en == 1'b1) begin
bit_cnt <= bit_cnt ;
end else begin
bit_cnt <= 3'd0 ;
end
end
end
end
end
// [7:0] rx_data ,
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
rx_data <= 8'd0 ;
end else begin
if(bit_cnt >= 4'd1 && bit_cnt <= 4'd8 && baud_cnt == BAUD_CNT_MAX / 2'd2) begin
rx_data <= {rx_reg3, rx_data[7:1]} ;
end else begin
rx_data <= rx_data ;
end
end
end
// rx_flag
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
rx_flag <= 1'b0 ;
end else begin
if(bit_cnt == 4'd8 && bit_flag == 1'b1) begin
rx_flag <= 1'b1 ;
end else begin
rx_flag <= 1'b0 ;
end
end
end
// output signal
// po_flag
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
po_flag <= 1'b0 ;
end else begin
if(rx_flag == 1'b1) begin
po_flag <= 1'b1 ;
end else begin
po_flag <= 1'b0 ;
end
end
end
// po_data
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
po_data <= 8'd0 ;
end else begin
if(rx_flag == 1'b1) begin
po_data <= rx_data ;
end else begin
po_data <= 8'd0 ;
end
end
end
endmodule
module top (
input wire sys_clk ,
input wire sys_rst_n ,
input wire rx ,
inout wire [23:0] lcd_rgb ,
output wire lcd_de ,
output wire lcd_bl ,
output wire lcd_rstn ,
output wire lcd_hsync ,
output wire lcd_vsync ,
output wire lcd_clk
);
// inout
wire [23:0] lcd_rgb_out ;
wire [23:0] lcd_rgb_in ;
assign lcd_rgb = (lcd_de) ? lcd_rgb_out : 24'dz ;
assign lcd_rgb_in = lcd_rgb ;
// 例化间连线
wire [15:0] lcd_id ;
wire clk_lcd ;
wire rst_n ;
wire [10:0] H_SYNCtoDIS ;
wire [10:0] H_BACKtoDIS ;
wire [10:0] H_DISPtoDIS ;
wire [10:0] V_SYNCtoDIS ;
wire [10:0] V_BACKtoDIS ;
wire [10:0] V_DISPtoDIS ;
wire [10:0] axi_x ;
wire [10:0] axi_y ;
wire [23:0] pix_data ;
wire [7:0] po_data ;
wire po_flag ;
wire clk_rx ;
rd_id rd_id_inst(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.lcd_rgb ( lcd_rgb_in ) ,
.lcd_id ( lcd_id )
);
clk_div clk_div_inst(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.lcd_id ( lcd_id ) ,
.clk_rx ( clk_rx ) ,
.clk_lcd ( clk_lcd ) ,
.rst_n ( rst_n )
);
lcd_driver lcd_driver_inst(
.sys_clk ( clk_lcd ) ,
.sys_rst_n ( rst_n ) ,
.pix_data ( pix_data ) ,
.lcd_id ( lcd_id ) ,
.H_SYNCtoDIS ( H_SYNCtoDIS ) ,
.H_BACKtoDIS ( H_BACKtoDIS ) ,
.H_DISPtoDIS ( H_DISPtoDIS ) ,
.V_SYNCtoDIS ( V_SYNCtoDIS ) ,
.V_BACKtoDIS ( V_BACKtoDIS ) ,
.V_DISPtoDIS ( V_DISPtoDIS ) ,
.lcd_de ( lcd_de ) ,
.lcd_rgb_out ( lcd_rgb_out ) ,
.lcd_bl ( lcd_bl ) ,
.lcd_rstn ( lcd_rstn ) ,
.lcd_hsync ( lcd_hsync ) ,
.lcd_vsync ( lcd_vsync ) ,
.lcd_clk ( lcd_clk ) ,
.axi_x ( axi_x ) ,
.axi_y ( axi_y )
);
lcd_display lcd_display_inst(
.sys_clk ( clk_lcd ) ,
.sys_rst_n ( rst_n ) ,
.axi_x ( axi_x ) ,
.axi_y ( axi_y ) ,
.pi_data ( po_data ) ,
.pi_flag ( po_flag ) ,
.clk_wr_ram ( clk_rx ) ,
.H_SYNC ( H_SYNCtoDIS ) ,
.H_BACK ( H_BACKtoDIS ) ,
.H_DISP ( H_DISPtoDIS ) ,
.V_SYNC ( V_SYNCtoDIS ) ,
.V_BACK ( V_BACKtoDIS ) ,
.V_DISP ( V_DISPtoDIS ) ,
.pix_data ( pix_data )
);
rx rx_inst(
.sys_clk ( clk_rx ) ,
.sys_rst_n ( rst_n ) ,
.rx ( rx ) ,
.po_data ( po_data ) ,
.po_flag ( po_flag )
);
endmodule