1
0
mirror of https://github.com/WangXuan95/FpOC.git synced 2025-02-05 08:08:22 +08:00
FpOC/RTL/uart_monitor.sv

189 lines
5.5 KiB
Systemverilog
Raw Normal View History

2021-02-22 14:17:59 +08:00
2022-04-01 05:22:10 +08:00
// 模块uart_monitor
// Type : synthesizable
// Standard: SystemVerilog 2005 (IEEE1800-2005)
2021-02-22 14:17:59 +08:00
// 功能UART发送器格式为115200,8,n,1可以把 i_val0, i_val1, i_val2, i_val3 变成10进制格式放在一行里通过 UART 发送出去,
2022-04-01 05:22:10 +08:00
2021-02-22 14:17:59 +08:00
module uart_monitor #(
parameter [15:0] CLK_DIV = 217 // UART分频倍率例如若时钟频率为 36.864MHz, CLK_DIV=320则 UART 波特率为 36.864MHz/320=115200
) (
input wire rstn,
input wire clk,
input wire i_en,
input wire signed [15:0] i_val0,
input wire signed [15:0] i_val1,
input wire signed [15:0] i_val2,
input wire signed [15:0] i_val3,
2022-04-01 05:22:10 +08:00
output reg o_uart_tx // UART TX 信号
2021-02-22 14:17:59 +08:00
);
2022-04-01 05:22:10 +08:00
initial o_uart_tx = 1'b1;
2021-02-22 14:17:59 +08:00
enum logic [2:0] {IDLE, SELECT, WAIT, PARSING, SENDING} stat;
wire tx_rdy;
reg tx_en;
reg [7:0] tx_data;
reg itoa_en;
reg signed [15:0] itoa_val;
2022-04-01 05:22:10 +08:00
reg itoa_oen;
reg [ 7:0] itoa_str [6];
2021-02-22 14:17:59 +08:00
reg [ 2:0] vcnt;
reg [ 2:0] cnt;
reg [ 7:0] eov;
wire [ 7:0] s_str[8];
assign s_str[0] = itoa_str[0];
assign s_str[1] = itoa_str[1];
assign s_str[2] = itoa_str[2];
assign s_str[3] = itoa_str[3];
assign s_str[4] = itoa_str[4];
assign s_str[5] = itoa_str[5];
assign s_str[6] = 8'h20;
assign s_str[7] = eov;
always_comb begin
tx_en = 1'b0;
tx_data = '0;
if(stat==SENDING) begin
tx_en = 1'b1;
tx_data = s_str[cnt];
end
end
always @ (posedge clk or negedge rstn)
if(~rstn) begin
stat <= IDLE;
itoa_en <= 1'b0;
itoa_val <= '0;
vcnt <= '0;
cnt <= '0;
eov <= 8'h20;
end else begin
itoa_en <= 1'b0;
case(stat)
IDLE: if(i_en)
stat <= SELECT;
SELECT: begin
if (vcnt==3'd0) begin
vcnt <= vcnt + 3'd1;
stat <= WAIT;
itoa_en <= 1'b1;
itoa_val <= i_val0;
eov <= 8'h20;
end else if(vcnt==3'd1) begin
vcnt <= vcnt + 3'd1;
stat <= WAIT;
itoa_en <= 1'b1;
itoa_val <= i_val1;
eov <= 8'h20;
end else if(vcnt==3'd2) begin
vcnt <= vcnt + 3'd1;
stat <= WAIT;
itoa_en <= 1'b1;
itoa_val <= i_val2;
eov <= 8'h20;
end else if(vcnt==3'd3) begin
vcnt <= vcnt + 3'd1;
stat <= WAIT;
itoa_en <= 1'b1;
itoa_val <= i_val3;
eov <= 8'h0A;
end else begin
vcnt <= 3'd0;
stat <= IDLE;
eov <= 8'h20;
end
end
WAIT:
stat <= PARSING;
PARSING: if(itoa_oen)
stat <= SENDING;
SENDING: if(tx_rdy) begin
cnt <= cnt + 3'd1;
if(cnt==3'd7)
stat <= SELECT;
end
endcase
end
2022-04-01 05:22:10 +08:00
reg [ 2:0] itoa_cnt;
reg itoa_sign;
reg itoa_zero;
reg [15:0] itoa_abs;
reg [ 3:0] itoa_rem;
always @ (posedge clk or negedge rstn)
if(~rstn) begin
itoa_cnt <= 3'd0;
{itoa_sign, itoa_abs, itoa_zero, itoa_rem} <= '0;
itoa_oen <= 1'b0;
itoa_str <= '{6{'0}};
end else begin
if(itoa_cnt==3'd0) begin
if(itoa_en)
itoa_cnt <= 3'd1;
itoa_sign <= itoa_val[15];
itoa_abs <= itoa_val[15] ? $unsigned(-itoa_val) : $unsigned(itoa_val);
end else begin
itoa_cnt <= itoa_cnt + 3'd1;
itoa_abs <= itoa_abs / 16'd10;
itoa_rem <= (4)'(itoa_abs % 16'd10);
itoa_zero <= itoa_abs==16'd0;
if(itoa_cnt>3'd1) begin
itoa_str[5] <= itoa_str[4];
itoa_str[4] <= itoa_str[3];
itoa_str[3] <= itoa_str[2];
itoa_str[2] <= itoa_str[1];
itoa_str[1] <= itoa_str[0];
if(itoa_cnt>3'd2 && itoa_zero) begin
itoa_str[0] <= itoa_sign ? 8'h2D : 8'h20;
itoa_sign <= 1'b0;
end else begin
itoa_str[0] <= {4'h3, itoa_rem};
end
end
end
itoa_oen <= itoa_cnt == 3'd7;
end
reg [15:0] ccnt;
reg [ 3:0] tx_cnt;
reg [12:1] tx_shift;
assign tx_rdy = (tx_cnt==4'd0);
always @ (posedge clk or negedge rstn)
if(~rstn) begin
o_uart_tx <= 1'b1;
ccnt <= '0;
tx_cnt <= '0;
tx_shift <= '1;
end else begin
if(tx_cnt==4'd0) begin
o_uart_tx <= 1'b1;
ccnt <= '0;
if(tx_en) begin
tx_cnt <= 4'd12;
tx_shift <= {2'b10, tx_data[0], tx_data[1], tx_data[2], tx_data[3], tx_data[4], tx_data[5], tx_data[6], tx_data[7], 2'b11};
end
end else begin
o_uart_tx <= tx_shift[tx_cnt];
if( ccnt + 16'd1 < CLK_DIV ) begin
ccnt <= ccnt + 16'd1;
end else begin
ccnt <= '0;
tx_cnt <= tx_cnt - 4'd1;
end
end
end
2021-02-22 14:17:59 +08:00
endmodule