基本代码全部完成,等待验证

This commit is contained in:
yangshenbo 2026-04-06 16:03:22 +08:00
parent 8213e6443c
commit 35f9c31fe0
3 changed files with 132 additions and 63 deletions

View File

@ -55,7 +55,9 @@ wire [23:0] therm_out;
.o_addr (w_addr),
.o_wren (w_wren),
.o_rden (w_rden),
.i_rddata (w_rddata)
.i_rddata (w_rddata),
.i_report_data (therm_out),
.i_report_vld (therm_vld)
);
system_regfile u_system_regfile (

View File

@ -15,6 +15,9 @@ module uart_ctrl_sysreg #(
,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 ---
@ -39,7 +42,6 @@ module uart_ctrl_sysreg #(
reg [31:0]wr_data_buff;
reg [19:0] data_bytes_len;
// 状态机定义
reg [2:0] state;
localparam S_IDLE = 3'd0,
@ -47,9 +49,26 @@ module uart_ctrl_sysreg #(
S_PARSE = 3'd2,
S_WAIT_RD = 3'd3,
S_RD_DATA = 3'd4,
S_WR_DATA = 3'd5;
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
@ -70,6 +89,9 @@ module uart_ctrl_sysreg #(
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
@ -109,10 +131,15 @@ module uart_ctrl_sysreg #(
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
@ -122,4 +149,5 @@ module uart_ctrl_sysreg #(
endmodule

View File

@ -30,72 +30,87 @@ module TB_top();
.sig_in (sig_in)
);
// ==========================================
// 任务:发送一个字节 (Serial TX)
// ==========================================
task automatic send_byte(input [7:0] data);
begin
uart_rx = 0; // 起始位
#(BIT_TIME);
for (int i = 0; i < 8; i++) begin
uart_rx = data[i]; // LSB First
#(BIT_TIME);
end
uart_rx = 1; // 停止位
#(BIT_TIME);
end
endtask
// 任务:发送 32/64 位数据
task automatic send_data(input [63:0] data, input int len_bits);
int bytes = len_bits / 8;
for (int i = bytes - 1; i >= 0; i--) begin // 从最高字节往下发
send_byte(data[i*8 +: 8]);
end
endtask
// ==========================================
// 流程控制TX 驱动 (从 case.txt 读取)
// ==========================================
// // ==========================================
// // 流程控制TX 驱动 (从 case.txt 读取)
// // ==========================================
// initial begin
// int file_h;
// int status;
// logic [63:0] val;
// // 初始化信号
// rst_n = 0;
// uart_rx = 1;
// #(CLK_PERIOD * 10);
// rst_n = 1;
// file_h = $fopen("case.txt", "r");
// if (!file_h) begin
// $display("[TX ERROR] Cannot open case.txt");
// $finish;
// end
// $display("[TX] Starting transmission...");
// while (!$feof(file_h)) begin
// // 假设文件中每行是一个 hex 数据
// status = $fscanf(file_h, "%h\n", val);
// if (status == 1) begin
// if (val > 64'hFFFF_FFFF) begin
// $display("[%t] TX CMD: %h", $time, val);
// send_data(val, 64);
// end else begin
// $display("[%t] TX DATA: %h", $time, val[31:0]);
// send_data(val[31:0], 32);
// end
// #(BIT_TIME * 5); // 帧间隙
// end
// end
// $fclose(file_h);
// $display("[TX] All cases sent.");
// // 等待一段时间观察 RX 是否还有回传,然后结束
// #(BIT_TIME * 500);
// $display("[SIM] Simulation finished.");
// $finish;
// end
initial begin
int file_h;
int status;
logic [63:0] val;
// 初始化信号
rst_n = 0;
uart_rx = 1;
#(CLK_PERIOD * 10);
// 1. 初始化
rst_n = 0; uart_rx = 1; sig_in = 0;
#(CLK_PERIOD * 20);
rst_n = 1;
file_h = $fopen("case.txt", "r");
if (!file_h) begin
$display("[TX ERROR] Cannot open case.txt");
$finish;
end
#(CLK_PERIOD * 100);
$display("[TX] Starting transmission...");
$display("------- Step 1: Configure Thermometer Regs -------");
send_data(64'h80000004_00000004,64);
send_data(64'h80000008_00000004,64);
send_data(64'h8000000c_00000004,64);
send_data(64'h80000010_00000004,64);
send_data(64'h80000014_00000004,64);
while (!$feof(file_h)) begin
// 假设文件中每行是一个 hex 数据
status = $fscanf(file_h, "%h\n", val);
if (status == 1) begin
if (val > 64'hFFFF_FFFF) begin
$display("[%t] TX CMD: %h", $time, val);
send_data(val, 64);
end else begin
$display("[%t] TX DATA: %h", $time, val[31:0]);
send_data(val[31:0], 32);
end
#(BIT_TIME * 5); // 帧间隙
$display("------- Step 2: Running Concurrent Tasks -------");
fork
// 进程 A: 模拟输入脉冲 (代表温度变化)
begin
gen_pulses(400, 10); // 100kHz 持续 10ms
end
end
$fclose(file_h);
$display("[TX] All cases sent.");
// 进程 B: 在上报期间,强行插口读取指令
begin
#(2_000000); // 等待第一个上报包可能发出
$display("[%t] TX: Sending Read Request during active reporting...", $time);
send_data(64'h80000014_00000004,64);
send_data(64'h00000010_00000004,64);send_data(32'h8000_06e8,32);
send_data(64'h00000010_00000004,64);send_data(32'h8000_06e8,32);
end
join
// 等待一段时间观察 RX 是否还有回传,然后结束
#(BIT_TIME * 500);
$display("[SIM] Simulation finished.");
$display("Test Done.");
$finish;
end
@ -177,4 +192,28 @@ module TB_top();
end
endtask
// ==========================================
// 任务:发送一个字节 (Serial TX)
// ==========================================
task automatic send_byte(input [7:0] data);
begin
uart_rx = 0; // 起始位
#(BIT_TIME);
for (int i = 0; i < 8; i++) begin
uart_rx = data[i]; // LSB First
#(BIT_TIME);
end
uart_rx = 1; // 停止位
#(BIT_TIME);
end
endtask
// 任务:发送 32/64 位数据
task automatic send_data(input [63:0] data, input int len_bits);
int bytes = len_bits / 8;
for (int i = bytes - 1; i >= 0; i--) begin // 从最高字节往下发
send_byte(data[i*8 +: 8]);
end
endtask
endmodule