【UART 读取 RAM】

上电初始在 RAM 中写入比其地址大一的数据,写入完成点亮 LED[0]进行指示;此时 RAM 中存储 256 个 8bit 数据,等待 UART 接收到一个字节数据;以此数据作为地址,读出该地址对应的数据;然后通过 UART 发送出去。

顶层模块

module top_uart(
	input	wire 			sclk,
	input	wire 			rst_n,
	input	wire 			rx,
	output	wire 			tx,
	output wire led
	);
wire 		flag;
wire [7:0]	data;
wire  rd_flag;
wire [7:0]	rd_data;
wire clk_lock;
wire clk_50;
	uart_rx  inst_uart_rx (
			.sclk    (sclk),
			.rst_n   (rst_n),
			.rx      (rx),
			.po_data (data),
			.po_flag (flag)
		);
	uart_tx inst_uart_tx (
			.sclk    (sclk),
			.rst_n   (rst_n),
			.pi_flag (rd_flag),
			.pi_data (rd_data),
			.tx      (tx)
		);
 ram_trcl inst_ram_crtl(
 	.clk(sclk),
	.rst_n(rst_n),
	.rx_data(data),
	.pi_flag(flag), 
    .rd_data(rd_data),
	.led(led),
	.rd_flag(rd_flag)
	);
endmodule 

uart_rx模块

module uart_rx(
	input	wire 				sclk,
	input	wire 				rst_n,
	input	wire 				rx,
	output	reg 	[7:0]		po_data,
	output	reg 				po_flag
	);

parameter 	CNT_BAUD_MAX =5207;
parameter	CNT_HALF_BAUD_MAX =2603;
reg 			rx1,rx2,rx2_reg;
reg 			rx_flag;
reg 	[12:0]	cnt_baud;
reg 			bit_flag;
reg [2:0]num;
reg 	[3:0]	bit_cnt;

always @(posedge sclk) begin
	{rx2_reg,rx2,rx1}<={rx2,rx1,rx};
end


always @(posedge sclk or negedge  rst_n) begin
	if (rst_n == 1'b0) begin
		rx_flag <= 1'b0;
	end
	else if (bit_cnt == 4'd8 && bit_flag == 1'b1) begin
		rx_flag <= 1'b0;
	end
	else if (rx2_reg == 1'b1 && rx2 == 1'b0) begin
		rx_flag <= 1'b1;
	end
end
always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		cnt_baud <= 'd0;
	end
	else if (rx_flag == 1'b0) begin
		cnt_baud <= 'd0;
	end
	else if (rx_flag == 1'b1 && cnt_baud == CNT_BAUD_MAX) begin
		cnt_baud <= 'd0;
	end
	else if (rx_flag == 1'b1) begin
		cnt_baud <= cnt_baud + 1'b1;
	end
end
always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		bit_flag <= 1'b0;
	end
	else if (rx_flag == 1'b1 && cnt_baud == CNT_HALF_BAUD_MAX) begin
		bit_flag <= 1'b1;
	end
	else begin
		bit_flag <= 1'b0;
	end
end
always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		bit_cnt <= 'd0;
	end
	else if (bit_flag == 1'b1 && bit_cnt == 'd8) begin
		bit_cnt <= 'd0;
	end
	else if (bit_flag == 1'b1) begin
		bit_cnt <= bit_cnt + 1'b1;
	end
end
always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		po_data <='d0;
	end
	else if (bit_cnt >= 4'd1 && bit_flag == 1'b1) begin
		po_data <= {rx2_reg,po_data[7:1]};
	end
end
always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin	
		po_flag <= 1'b0;
	end
	else if (bit_cnt == 4'd8 && bit_flag == 1'b1) begin
		po_flag <= 1'b1;
	end
	else begin
		po_flag <= 1'b0;
	end
end
endmodule 

uart_tx模块

module uart_tx(
	input	wire 			sclk,
	input	wire 			rst_n,
	input	wire 			pi_flag,
	input	wire 	[7:0]	pi_data,
	output	reg 			tx
	);
parameter CNT_BAUD_MAX =5207;
reg 	[7:0]	data_reg;
reg 			tx_flag,pi_flag2;
reg 	[12:0]	cnt_baud;
reg 			bit_flag;
reg 	[3:0]	bit_cnt;
always @(posedge sclk or negedge  rst_n) begin
	if (rst_n == 1'b0) begin
		pi_flag2 <='d0;
	end
	else if (pi_flag == 1'b1) begin
		pi_flag2 <=1;
	end
	else pi_flag2 <='d0;
end
always @(posedge sclk or negedge  rst_n) begin
	if (rst_n == 1'b0) begin
		data_reg <='d0;
	end
	else if (pi_flag2 == 1'b1) begin
		data_reg <= pi_data;
	end
end
always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		tx_flag <= 1'b0;
	end
	else if(bit_flag == 1'b1 && bit_cnt == 4'd8) begin
		tx_flag <= 1'b0;
	end
	else if (pi_flag == 1'b1) begin
		tx_flag <= 1'b1;
	end
end

always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		cnt_baud <= 'd0;
	end
	else if(tx_flag == 1'b0)begin
		cnt_baud <='d0;
	end
	else if (tx_flag == 1'b1 && cnt_baud == CNT_BAUD_MAX) begin
		cnt_baud <= 'd0;
	end
	else if (tx_flag == 1'b1) begin
		cnt_baud <= cnt_baud + 1'b1;
	end
end

always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		bit_flag <= 1'b0;
	end
	else if (cnt_baud == CNT_BAUD_MAX -1  && tx_flag == 1'b1) begin
		bit_flag <= 1'b1;
	end
	else begin
		bit_flag <= 1'b0;
	end
end


always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		bit_cnt <= 'd0;
	end
	else if(bit_flag == 1'b1 &&  bit_cnt == 4'd8) begin
		bit_cnt <= 'd0;
	end
	else if (bit_flag == 1'b1) begin
		bit_cnt <= bit_cnt + 1'b1;
	end
end

always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		tx <= 1'b1;
	end
	else if (pi_flag == 1'b1) begin
		tx <= 1'b0;
	end
	else if (bit_cnt<=7 && bit_flag == 1'b1) begin
		tx <= data_reg[bit_cnt];
	end
	else if (bit_flag == 1'b1 && bit_cnt == 4'd8) begin
		tx <= 1'b1;
	end
end


endmodule 

ram_trcl模块

module ram_trcl(
	input	wire 				clk,
	input	wire 				rst_n,
	input	wire	[7:0]		rx_data,
	input	wire				pi_flag, 
    output  wire  [7:0] rd_data,
	output reg led,
	output reg rd_flag
	);
reg [7:0] wr_addr,rd_addr,pi_data;
reg rd_en; //读写使能位,1-写,0-读
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		rd_en <= 1'b1;
		led<=1;
	end
	else if (wr_addr == 'd255) begin
		rd_en <= 1'b0;
		led<=0;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		wr_addr <= 'b0;
		pi_data <= 'b1;
	end
	else if (rd_en == 1'b1) begin
		wr_addr <= wr_addr + 1'b1;
		pi_data <= pi_data +1'b1;
	end
	else begin
		wr_addr <= 'b0;
		pi_data <= 1'b0;
	end
end
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		rd_addr <= 'd0;
	end
	else if (rd_en == 1'b0 && pi_flag==1) begin
		rd_addr <= rx_data;
	end
	else begin
		rd_addr <= 'd0;
	end
end
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		rd_flag <= 'd0;
	end
	else if (rd_en == 1'b0 && pi_flag==1) begin
		rd_flag <= 'd1;
	end
	else begin
		rd_flag <= 'd0;
	end
end

blk_mem_gen_0 uut_arm (
  .clka(clk),    // input wire clka
  .wea(rd_en),      // input wire [0 : 0] wea
  .addra(wr_addr),  // input wire [7 : 0] addra
  .dina(pi_data),    // input wire [7 : 0] dina
  .clkb(clk),    // input wire clkb
  .addrb(rd_addr),  // input wire [7 : 0] addrb
  .doutb(rd_data)  // output wire [7 : 0] doutb
);
endmodule

顶层模块仿真图请添加图片描述

下板验证结果:

请添加图片描述

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值