hdl4se_uart_ctrl_axi.v 5.0 KB
Newer Older
饶先宏's avatar
饶先宏 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147

`timescale 1 ns / 1 ps

module hdl4se_uart_ctrl_axi
(
		input wire			s00_axi_aclk,
		input wire			s00_axi_aresetn,
		input wire [3 : 0]	s00_axi_awaddr,
		input wire [2 : 0]	s00_axi_awprot,
		input wire			s00_axi_awvalid,
		output wire			s00_axi_awready,
		input wire [31 : 0] s00_axi_wdata,
		input wire [3 : 0]	s00_axi_wstrb,
		input wire			s00_axi_wvalid,
		output wire			s00_axi_wready,
		output wire [1 : 0] s00_axi_bresp,
		output wire			s00_axi_bvalid,
		input wire			s00_axi_bready,
		input wire [3 : 0]	s00_axi_araddr,
		input wire [2 : 0]	s00_axi_arprot,
		input wire			s00_axi_arvalid,
		output wire			s00_axi_arready,
		output wire [31:0]	s00_axi_rdata,
		output wire [1 : 0] s00_axi_rresp,
		output wire			s00_axi_rvalid,
		input wire			s00_axi_rready,
		output				uart_tx,
		input				uart_rx,
		output				dataready,
		output				sendready,
		output				sendfull,
		output				recvempty
);

	/* uart and buffer */
	wire [31:0] ctl_state;

	reg [7:0]  send_buf_data;
	wire [7:0] send_buf_q;
	wire send_buf_full;
	wire send_buf_empty;
	wire [9:0] send_buf_used;
	reg send_buf_read;
	reg send_buf_write;
	
    uart_fifo_gen uart_send_buf(
		.clock(s00_axi_aclk),
		.rst(~s00_axi_aresetn),
		.data(send_buf_data),
		.rdreq(send_buf_read),
		.wrreq(send_buf_write),
		.empty(send_buf_empty),
		.full(send_buf_full),
		.q(send_buf_q),
		.usedw(send_buf_used));


	reg [7:0]  recv_buf_data;
	wire [7:0] recv_buf_q;
	wire recv_buf_empty;
	wire recv_buf_full;
	wire [9:0] recv_buf_used;
	reg recv_buf_read;
	reg recv_buf_write;
	
    uart_fifo_gen uart_recv_buf(
		.clock(s00_axi_aclk),
		.rst(~s00_axi_aresetn),
		.data(recv_buf_data),
		.rdreq(recv_buf_read),
		.wrreq(recv_buf_write),
		.empty(recv_buf_empty),
		.full(recv_buf_full),
		.q(recv_buf_q),
		.usedw(recv_buf_used));

	reg  send, recv;
	reg [7:0] senddata;
	wire [7:0] recvdata;
	wire uart_has_data;
	wire uart_can_send;
	reg [15:0] divsor;

	hdl4se_uart uart_u(
		.wClk(s00_axi_aclk), 
		.nwReset(s00_axi_aresetn),
		.divsor(divsor),
		//send
		.cansend(uart_can_send),
		.send(send),
		.senddata(senddata),
		.txd(uart_tx),
		//recv
		.hasdata(uart_has_data),
		.recvdata(recvdata),
		.recv(recv),
		.rxd(uart_rx)
	);

	assign sendfull = send_buf_full;
	assign recvempty = recv_buf_empty;
	assign dataready = uart_has_data;
	assign sendready = uart_can_send;

	reg [2:0] waitclk;
	always @(posedge s00_axi_aclk)	
	if (~s00_axi_aresetn) begin
		send <= 1'b0;
		recv <= 1'b0;
		senddata <= 0;
		recv_buf_write <= 1'b0;
		send_buf_read <= 1'b0;
		waitclk <= 0;
	end else begin
		send <= 1'b0;
		recv <= 1'b0;
		recv_buf_write <= 1'b0;
		send_buf_read <= 1'b0;
		if (waitclk == 0) begin
			if (uart_has_data && ~recv_buf_full) begin
				recv <= 1;
				recv_buf_data <= recvdata;
				recv_buf_write <= 1'b1;
				waitclk <= 4;
			end else if (uart_can_send && ~send_buf_empty) begin
				send_buf_read <= 1'b1;
				send <= 1;
				senddata <= send_buf_q;
				waitclk <= 4;
			end 
		end else begin
			waitclk <= waitclk - 1;
		end
	end

	assign ctl_state = {28'h0, send_buf_full, send_buf_empty, recv_buf_full, ~recv_buf_empty};

	/* axi bus */
	reg [1 : 0] 	axi_bresp;
	reg  			axi_bvalid;
	reg  			axi_arready;
	reg [31 : 0] 	axi_rdata;
	reg [1 : 0] 	axi_rresp;
	reg  			axi_rvalid;
	wire			slv_reg_rden;
	wire			slv_reg_wren;

饶先宏's avatar
饶先宏 已提交
148 149
	assign s00_axi_awready = 1'b1;
	assign s00_axi_wready = 1'b1;
饶先宏's avatar
饶先宏 已提交
150 151 152 153 154 155 156
	assign s00_axi_bresp	= axi_bresp;
	assign s00_axi_bvalid	= axi_bvalid;
	assign s00_axi_arready = axi_arready;
	assign s00_axi_rvalid = axi_rvalid;
	assign s00_axi_rdata = axi_rdata;
	assign s00_axi_rresp = axi_rresp;

饶先宏's avatar
饶先宏 已提交
157
	assign slv_reg_wren = s00_axi_wvalid && s00_axi_awvalid;
饶先宏's avatar
饶先宏 已提交
158 159 160 161 162 163 164 165

	always @( posedge s00_axi_aclk )
	begin
		if ( s00_axi_aresetn == 1'b0 ) begin
			divsor <= 50000000 / 115200;
			send_buf_write <= 0;
	    end else if (slv_reg_wren) begin
			send_buf_write <= 0;
饶先宏's avatar
饶先宏 已提交
166
			if ((s00_axi_awaddr & 4'hf) == 4'h4) begin
饶先宏's avatar
饶先宏 已提交
167 168
				send_buf_data <= s00_axi_wdata;
				send_buf_write <= ~recv_buf_full;
饶先宏's avatar
饶先宏 已提交
169
			end else if ((s00_axi_awaddr & 4'hf) == 4'hc) begin
饶先宏's avatar
饶先宏 已提交
170 171
				divsor <= s00_axi_wdata[15:0];
			end
饶先宏's avatar
饶先宏 已提交
172 173
		end else begin
			send_buf_write <= 0;
饶先宏's avatar
饶先宏 已提交
174 175 176 177 178 179 180 181
		end
	end    

	always @( posedge s00_axi_aclk )
	begin
		if ( s00_axi_aresetn == 1'b0 ) begin
			axi_bvalid  <= 0;
			axi_bresp   <= 2'b0;
饶先宏's avatar
饶先宏 已提交
182
	    end else if (slv_reg_wren) begin
饶先宏's avatar
饶先宏 已提交
183 184 185
			axi_bvalid <= 1'b1;
	        axi_bresp  <= 2'b0; // 'OKAY' response 
	    end else if (s00_axi_bready && axi_bvalid) begin
饶先宏's avatar
饶先宏 已提交
186
	        axi_bvalid <= 1'b0; 
饶先宏's avatar
饶先宏 已提交
187 188 189 190 191 192 193
	    end
	end   

	always @( posedge s00_axi_aclk )
	begin
		if ( s00_axi_aresetn == 1'b0 ) begin
			axi_rdata  <= 0;
饶先宏's avatar
饶先宏 已提交
194
			axi_rvalid <= 0;
饶先宏's avatar
饶先宏 已提交
195
			recv_buf_read <= 1'b0;
饶先宏's avatar
饶先宏 已提交
196 197
			axi_rresp <= 0;
	    end else if (s00_axi_arvalid) begin
饶先宏's avatar
饶先宏 已提交
198
			recv_buf_read <= 1'b0;
饶先宏's avatar
饶先宏 已提交
199 200
			axi_rvalid <= 0;
			if ((s00_axi_araddr & 4'hf) == 8) begin /* read state */
饶先宏's avatar
饶先宏 已提交
201
				axi_rdata <= ctl_state; 
饶先宏's avatar
饶先宏 已提交
202 203
				axi_rvalid <= 1;
			end else if ((s00_axi_araddr & 4'hf) == 0) begin/* read recv */
饶先宏's avatar
饶先宏 已提交
204 205
				axi_rdata <= {recv_buf_empty, 23'b0, recv_buf_q};
				recv_buf_read <= ~recv_buf_empty; 
饶先宏's avatar
饶先宏 已提交
206 207
				axi_rvalid <= 1;
			end
饶先宏's avatar
饶先宏 已提交
208
		end else begin
饶先宏's avatar
饶先宏 已提交
209 210
			recv_buf_read <= 0;
			axi_rvalid <= 0;
饶先宏's avatar
饶先宏 已提交
211 212 213 214
		end
	end    

endmodule