153 lines
4.5 KiB
Verilog
153 lines
4.5 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
|
|
//主动上报机制
|
|
,input [23:0] i_report_data
|
|
,input i_report_vld
|
|
);
|
|
|
|
// --- 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_WAIT_RD = 3'd3,
|
|
S_RD_DATA = 3'd4,
|
|
S_WR_DATA = 3'd5,
|
|
S_REPORT = 3'd6; //主动上报状态
|
|
|
|
|
|
// --- 主动上报数据先锁存着 ---
|
|
reg [23:0] report_data_latch;
|
|
reg report_pending;
|
|
|
|
// 捕捉上报脉冲:如果当前忙,先存起来
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if(!rst_n) begin
|
|
report_pending <= 1'b0;
|
|
report_data_latch <= 24'd0;
|
|
end else if(i_report_vld) begin
|
|
report_pending <= 1'b1;
|
|
report_data_latch <= i_report_data;
|
|
end else if(state == S_REPORT) begin
|
|
report_pending <= 1'b0; // 进入上报状态后清除标志
|
|
end
|
|
end
|
|
|
|
|
|
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
|
|
else if(report_pending) begin
|
|
state <= S_REPORT;
|
|
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_WAIT_RD;
|
|
end
|
|
else begin //写指令
|
|
state <= S_WR_DATA;
|
|
end
|
|
end
|
|
S_WAIT_RD : begin //3
|
|
o_rden <= 1'b0;
|
|
state <= S_RD_DATA;
|
|
end
|
|
S_RD_DATA :begin //4
|
|
uart_tx_data <= i_rddata;
|
|
uart_tx_go <= 1'b1;
|
|
state <= S_IDLE;
|
|
end
|
|
S_WR_DATA : begin //5
|
|
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
|
|
S_REPORT : begin //6
|
|
// 构造上报数据包,例如:[8'hAA (帧头) + 24'bit温度数据]
|
|
uart_tx_data <= {8'hAA, report_data_latch};
|
|
uart_tx_go <= 1'b1;
|
|
state <= S_IDLE;
|
|
end
|
|
|
|
default: state <= S_IDLE;
|
|
endcase
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
endmodule |