`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; assign s00_axi_awready = 1'b1; assign s00_axi_wready = 1'b1; 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; assign slv_reg_wren = s00_axi_wvalid && s00_axi_awvalid; 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; if ((s00_axi_awaddr & 4'hf) == 4'h4) begin send_buf_data <= s00_axi_wdata; send_buf_write <= ~recv_buf_full; end else if ((s00_axi_awaddr & 4'hf) == 4'hc) begin divsor <= s00_axi_wdata[15:0]; end end else begin send_buf_write <= 0; end end always @( posedge s00_axi_aclk ) begin if ( s00_axi_aresetn == 1'b0 ) begin axi_bvalid <= 0; axi_bresp <= 2'b0; end else if (slv_reg_wren) begin axi_bvalid <= 1'b1; axi_bresp <= 2'b0; // 'OKAY' response end else if (s00_axi_bready && axi_bvalid) begin axi_bvalid <= 1'b0; end end always @( posedge s00_axi_aclk ) begin if ( s00_axi_aresetn == 1'b0 ) begin axi_rdata <= 0; axi_rvalid <= 0; recv_buf_read <= 1'b0; axi_rresp <= 0; end else if (s00_axi_arvalid) begin recv_buf_read <= 1'b0; axi_rvalid <= 0; if ((s00_axi_araddr & 4'hf) == 8) begin /* read state */ axi_rdata <= ctl_state; axi_rvalid <= 1; end else if ((s00_axi_araddr & 4'hf) == 0) begin/* read recv */ axi_rdata <= {recv_buf_empty, 23'b0, recv_buf_q}; recv_buf_read <= ~recv_buf_empty; axi_rvalid <= 1; end end else begin recv_buf_read <= 0; axi_rvalid <= 0; end end endmodule