121 lines
3.2 KiB
Verilog
121 lines
3.2 KiB
Verilog
`timescale 1ns / 1ps
|
|
|
|
module uart_ctrl_sysreg #(
|
|
parameter BAUD = 115200,
|
|
parameter CLOCK_FREQ = 50_000_000
|
|
)(
|
|
input clk
|
|
,input rst_n
|
|
// 串口接口
|
|
,input uart_rx
|
|
,output uart_tx
|
|
//5口
|
|
,output reg [31:0] o_wrdata //write data to sram
|
|
,output reg [24:0] o_addr //sram address
|
|
,output reg o_wren //write enable sram
|
|
,output reg o_rden //rden enable sram
|
|
,input [31:0] i_rddata //read data from sram
|
|
);
|
|
|
|
// --- uart_top ---
|
|
wire [31:0] uart_rx_data;
|
|
wire uart_rx_done;
|
|
reg [31:0] uart_tx_data;
|
|
reg uart_tx_go;
|
|
wire uart_tx_done;
|
|
uart_top_32bit #(
|
|
.BAUD(BAUD),
|
|
.CLOCK_FREQ(CLOCK_FREQ)
|
|
) uart_32bit_inst (
|
|
.Clk(clk), .Reset_n(rst_n),
|
|
.Send_Go32(uart_tx_go), .Tx_Data32(uart_tx_data), .Tx_Done32(uart_tx_done),
|
|
.uart_tx(uart_tx), .uart_rx(uart_rx),
|
|
.Rx_Done32(uart_rx_done), .Rx_Data32(uart_rx_data)
|
|
);
|
|
|
|
|
|
// 协议解析寄存器
|
|
reg [63:0] cmd_reg;
|
|
reg [31:0]wr_data_buff;
|
|
reg [19:0] data_bytes_len;
|
|
|
|
|
|
// 状态机定义
|
|
reg [2:0] state;
|
|
localparam S_IDLE = 3'd0,
|
|
S_RX_CMD_L = 3'd1,
|
|
S_PARSE = 3'd2,
|
|
S_RD_DATA = 3'd3,
|
|
S_WR_DATA = 3'd4;
|
|
|
|
|
|
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if(!rst_n) begin
|
|
state <= 0;
|
|
cmd_reg <= 0;
|
|
o_wrdata <= 0;
|
|
o_wren <= 0;
|
|
o_rden <= 0;
|
|
uart_tx_go <= 1'b0;
|
|
uart_tx_data <= 1'b0;
|
|
end
|
|
else begin
|
|
case(state)
|
|
S_IDLE : begin //0
|
|
uart_tx_go <= 1'b0;
|
|
if(uart_rx_done) begin
|
|
cmd_reg[63:32] <= uart_rx_data;
|
|
state <= S_RX_CMD_L;
|
|
end
|
|
end
|
|
S_RX_CMD_L : begin //1
|
|
if(uart_rx_done)begin
|
|
cmd_reg[31:0] <= uart_rx_data;
|
|
state <= S_PARSE;
|
|
end
|
|
end
|
|
S_PARSE : begin //2
|
|
o_addr <= cmd_reg[56:32];
|
|
data_bytes_len <= cmd_reg[19:0];
|
|
if(cmd_reg[63] == 1'b1) begin //读指令
|
|
o_rden <= 1'b1;
|
|
state <= S_RD_DATA;
|
|
end
|
|
else begin //写指令
|
|
state <= S_WR_DATA;
|
|
end
|
|
end
|
|
S_RD_DATA :begin //3
|
|
o_rden <= 1'b0;
|
|
uart_tx_data <= i_rddata;
|
|
uart_tx_go <= 1'b1;
|
|
state <= S_IDLE;
|
|
end
|
|
S_WR_DATA : begin //4
|
|
o_wren <= 1'b0;
|
|
if(data_bytes_len != 0)begin
|
|
if(uart_rx_done) begin
|
|
o_wrdata <= uart_rx_data;
|
|
o_wren <= 1'b1;
|
|
data_bytes_len <= data_bytes_len - 20'd4;
|
|
end
|
|
end
|
|
else begin
|
|
state <= S_IDLE;
|
|
end
|
|
|
|
end
|
|
|
|
|
|
endcase
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
endmodule |