From fe2550055b06f3a176091bc83f909ef890b9f467 Mon Sep 17 00:00:00 2001 From: Clo91eaf Date: Wed, 8 May 2024 00:56:28 +0800 Subject: [PATCH] feat: Add PC alias for Concise signal in PlantUML documentation The PlantUML documentation for the clock and binary signals now includes an alias for the Concise signal, which is represented as "PC". This improves clarity and consistency in the documentation. Refactor PuaCpu.v to fix initial program counter value --- dependencies/rtl/PuaCpu.v | 21 +++++++++--------- doc/plantuml.md | 29 +++++++++++++++++++++++-- format.gtkw | 40 ++++++++++++++++++++++++++++++++++ src/dut.rs | 45 ++++++++++++++++++++++++++------------- src/emulator.rs | 23 ++++++++++++++++++-- 5 files changed, 129 insertions(+), 29 deletions(-) create mode 100644 format.gtkw diff --git a/dependencies/rtl/PuaCpu.v b/dependencies/rtl/PuaCpu.v index 7250fd0..6ea8441 100644 --- a/dependencies/rtl/PuaCpu.v +++ b/dependencies/rtl/PuaCpu.v @@ -95,18 +95,19 @@ module FetchUnit( // playground/src/pipeline/fetch/FetchUnit.scala:9:7 input [31:0] io_instSram_rdata // playground/src/pipeline/fetch/FetchUnit.scala:10:14 ); - reg [63:0] pc; // playground/src/pipeline/fetch/FetchUnit.scala:16:19 - reg io_decodeStage_data_valid_REG; // playground/src/pipeline/fetch/FetchUnit.scala:26:49 + reg [63:0] pc; // playground/src/pipeline/fetch/FetchUnit.scala:16:19 + wire [31:0] _io_instSram_addr_T_4 = + io_ctrl_ctrlSignal_do_flush + ? io_ctrl_target[31:0] + : io_ctrl_ctrlSignal_allow_to_go ? pc[31:0] + 32'h4 : pc[31:0]; // playground/src/pipeline/fetch/FetchUnit.scala:10:14, :16:19, :19:8, src/main/scala/chisel3/util/Mux.scala:126:16 + reg io_decodeStage_data_valid_REG; // playground/src/pipeline/fetch/FetchUnit.scala:26:49 always @(posedge clock) begin // playground/src/pipeline/fetch/FetchUnit.scala:9:7 if (reset) begin // playground/src/pipeline/fetch/FetchUnit.scala:9:7 - pc <= 64'h7FFFFFFC; // playground/src/pipeline/fetch/FetchUnit.scala:16:{19,40} + pc <= 64'h7FFFFFF8; // playground/src/pipeline/fetch/FetchUnit.scala:16:{19,47} io_decodeStage_data_valid_REG <= 1'h0; // playground/src/pipeline/fetch/FetchUnit.scala:22:7, :26:49 end else begin // playground/src/pipeline/fetch/FetchUnit.scala:9:7 - if (io_ctrl_ctrlSignal_do_flush) // playground/src/pipeline/fetch/FetchUnit.scala:10:14 - pc <= io_ctrl_target; // playground/src/pipeline/fetch/FetchUnit.scala:16:19 - else if (io_ctrl_ctrlSignal_allow_to_go) // playground/src/pipeline/fetch/FetchUnit.scala:10:14 - pc <= pc + 64'h4; // playground/src/pipeline/fetch/FetchUnit.scala:16:19, :19:8 + pc <= {32'h0, _io_instSram_addr_T_4}; // playground/src/pipeline/fetch/FetchUnit.scala:16:19, src/main/scala/chisel3/util/Mux.scala:126:16 io_decodeStage_data_valid_REG <= ~reset; // playground/src/pipeline/fetch/FetchUnit.scala:26:{49,50} end end // always @(posedge) @@ -131,11 +132,11 @@ module FetchUnit( // playground/src/pipeline/fetch/FetchUnit.scala:9:7 `FIRRTL_AFTER_INITIAL // playground/src/pipeline/fetch/FetchUnit.scala:9:7 `endif // FIRRTL_AFTER_INITIAL `endif // ENABLE_INITIAL_REG_ - assign io_decodeStage_data_inst = {32'h0, io_instSram_rdata}; // playground/src/pipeline/fetch/FetchUnit.scala:9:7, :28:39 + assign io_decodeStage_data_inst = {32'h0, io_instSram_rdata}; // playground/src/pipeline/fetch/FetchUnit.scala:9:7, :16:19, :28:39 assign io_decodeStage_data_valid = io_decodeStage_data_valid_REG & ~reset; // playground/src/pipeline/fetch/FetchUnit.scala:9:7, :26:{49,74,76} assign io_decodeStage_data_pc = pc; // playground/src/pipeline/fetch/FetchUnit.scala:9:7, :16:19 - assign io_instSram_en = ~reset & pc[1:0] == 2'h0; // playground/src/pipeline/fetch/FetchUnit.scala:9:7, :16:19, :29:{44,51}, :32:{24,38} - assign io_instSram_addr = pc[31:0]; // playground/src/pipeline/fetch/FetchUnit.scala:9:7, :16:19, :31:21 + assign io_instSram_en = ~reset & pc[1:0] == 2'h0; // playground/src/pipeline/fetch/FetchUnit.scala:9:7, :16:19, :29:{44,51}, :31:{24,38} + assign io_instSram_addr = _io_instSram_addr_T_4; // playground/src/pipeline/fetch/FetchUnit.scala:9:7, src/main/scala/chisel3/util/Mux.scala:126:16 endmodule module DecodeStage( // playground/src/pipeline/decode/DecodeStage.scala:20:7 diff --git a/doc/plantuml.md b/doc/plantuml.md index 2a8ca9c..65a4524 100644 --- a/doc/plantuml.md +++ b/doc/plantuml.md @@ -5,7 +5,7 @@ clock "Clock" as C0 with period 50 binary "Reset" as B -concise "Concise" as C +concise "PC" as C @0 B is high @@ -29,7 +29,7 @@ C is 800f clock "Clock" as C0 with period 50 binary "Reset" as B -concise "Concise" as C +concise "PC" as C @0 B is high @@ -45,6 +45,31 @@ C is 8004 @200 C is 8008 +@250 +C is 800f +``` + +```plantuml +' !theme materia-outline + +clock "Clock" as C0 with period 50 +binary "Reset" as B +concise "PC" as C + +@0 +B is high +C is 7ffc + +@100 +B is low +C is 8000 + +@150 +C is 8004 + +@200 +C is 8008 + @250 C is 800f ``` \ No newline at end of file diff --git a/format.gtkw b/format.gtkw new file mode 100644 index 0000000..f56b118 --- /dev/null +++ b/format.gtkw @@ -0,0 +1,40 @@ +[*] +[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI +[*] Tue May 7 02:39:18 2024 +[*] +[dumpfile] "/home/clo91eaf/Project/Emulator/hemu/wave.vcd" +[dumpfile_mtime] "Tue May 7 02:33:24 2024" +[dumpfile_size] 41464 +[savefile] "/home/clo91eaf/Project/Emulator/hemu/format.gtkw" +[timestart] 0 +[size] 1908 1047 +[pos] -1 -1 +*-2.571706 36 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] TOP. +[treeopen] TOP.top. +[treeopen] TOP.top.core. +[treeopen] TOP.top.core.core. +[sst_width] 214 +[signals_width] 198 +[sst_expanded] 1 +[sst_vpaned_height] 309 +@28 +[color] 1 +TOP.clock +[color] 1 +TOP.reset +@22 +[color] 3 +TOP.top.core.core.FetchUnit.pc[63:0] +@200 +- +@22 +TOP.inst_sram_addr[31:0] +@28 +TOP.inst_sram_en +@22 +TOP.inst_sram_rdata[31:0] +TOP.inst_sram_wdata[31:0] +TOP.inst_sram_wen[3:0] +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/src/dut.rs b/src/dut.rs index 524acdb..4513e75 100644 --- a/src/dut.rs +++ b/src/dut.rs @@ -18,7 +18,9 @@ impl SramRequest { // sram interface pub struct Dut { top: Top, - pub clocks: u64, + clock: bool, + reset: bool, + pub ticks: u64, pub prepare_for_difftest: bool, } @@ -30,41 +32,54 @@ impl Dut { Dut { top, - clocks: 0, + clock: false, + reset: false, + ticks: 0, prepare_for_difftest: false, } } - fn eval(&mut self) { + fn clock_toggle(&mut self) { + self.clock = !self.clock; self.top.clock_toggle(); + } + + fn reset_toggle(&mut self) { + self.reset = !self.reset; + self.top.reset_toggle(); + } + + fn eval(&mut self) { + self.clock_toggle(); self.top.eval(); - self.top.trace_at(Duration::from_nanos(self.clocks * 10)); + self.top.trace_at(Duration::from_nanos(self.ticks * 2)); - self.top.clock_toggle(); + self.clock_toggle(); self.top.eval(); - self.top.trace_at(Duration::from_nanos(self.clocks * 10 + 5)); + self.top.trace_at(Duration::from_nanos(self.ticks * 2 + 1)); + self.ticks += 1; } /// drive the instruction SRAM interface pub fn step(&mut self, inst: u32, data: u64) -> anyhow::Result<(SramRequest, SramRequest, DebugInfo)> { - if self.clocks == 0 { - self.top.reset_toggle(); + if self.ticks == 0 { + self.reset_toggle(); } - if self.clocks == 5 { - self.top.reset_toggle(); + if self.ticks == 2 { + self.reset_toggle(); } - if self.clocks >= 5 { + // reset = 0 + if self.ticks >= 2 { self.top.set_inst_sram_rdata(inst); self.top.set_data_sram_rdata(data); } self.eval(); - self.clocks += 1; info!( - "[dut] clocks: {} commit: {} pc: {:#010x} wnum: {} wdata: {:#018x}", - self.clocks, + "[dut] ticks: {} commit: {} pc: {:#010x} wnum: {} wdata: {:#018x}", + self.ticks, self.top.debug_commit(), self.top.debug_pc(), self.top.debug_reg_wnum(), @@ -76,7 +91,7 @@ impl Dut { SramRequest::new(self.top.inst_sram_en() != 0, self.top.inst_sram_addr()), SramRequest::new(self.top.data_sram_en() != 0, self.top.data_sram_addr()), DebugInfo::new( - self.top.debug_commit() != 0, + self.top.debug_commit() != 0 && self.top.debug_reg_wnum() != 0, self.top.debug_pc(), self.top.debug_reg_wnum(), self.top.debug_wdata(), diff --git a/src/emulator.rs b/src/emulator.rs index 709fc6b..624d041 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -1,7 +1,7 @@ //! The emulator module represents an entire computer. use core::fmt; -use tracing::{ info, error }; +use tracing::{error, info, trace}; use crate::cpu::Cpu; use crate::dut::Dut; @@ -103,6 +103,7 @@ impl Emulator { fn dut_step(&mut self) -> DebugInfo { let mut inst: u32 = 0; let mut data: u64 = 0; + let mut ticks = 20; loop { let (inst_sram, data_sram, debug_info) = self.dut.step(inst, data).unwrap(); @@ -115,6 +116,12 @@ impl Emulator { // The result of the read method can be `Exception::LoadAccessFault`. In fetch(), an error // should be `Exception::InstructionAccessFault`. data = self.cpu.bus.read(p_addr, crate::cpu::DOUBLEWORD).unwrap(); + trace!( + "[dut] ticks:{} data_sram: addr={:#x} data={:#018x}", + self.dut.ticks, + data_sram.addr, + data + ); } if inst_sram.en { @@ -126,11 +133,23 @@ impl Emulator { // The result of the read method can be `Exception::LoadAccessFault`. In fetch(), an error // should be `Exception::InstructionAccessFault`. inst = self.cpu.bus.read(p_pc, crate::cpu::WORD).unwrap() as u32; + + trace!( + "[dut] ticks:{} data_sram: addr={:#x} inst={:#018x}", + self.dut.ticks, + inst_sram.addr, + inst + ); } if debug_info.commit { return debug_info; } + + ticks -= 1; + if ticks == 0 { + panic!("timeout"); + } } } @@ -145,7 +164,7 @@ impl Emulator { match trap { Trap::Fatal => { - info!("[cpu] pc: {:#x}, trap {:#?}", self.cpu.pc, trap); + info!("[cpu] fatal pc: {:#x}, trap {:#?}", self.cpu.pc, trap); return; } _ => {}