From 9f90b00b25467f4581eb70b956c65d355bc6c553 Mon Sep 17 00:00:00 2001 From: Yehowshua Immanuel Date: Thu, 28 Sep 2023 06:57:38 -0400 Subject: [PATCH] wow - loopback in sim actually worksgit status --- Makefile | 24 ++++++----------- bdpi/uart_sim_device.c | 21 +++++++++++++++ bram_tests/Testbench.bsv | 14 +++++----- old_src/ClkDivider.bs | 40 ---------------------------- old_src/Deserializer.bs | 53 ------------------------------------- old_src/Serializer.bs | 52 ------------------------------------- old_src/State.bs | 20 -------------- old_src/Top.bs | 56 ---------------------------------------- src/Core.bsv | 25 ++++++++++++++++-- src/Top.bsv | 52 ++++++++++++++++++++++++++----------- 10 files changed, 96 insertions(+), 261 deletions(-) delete mode 100644 old_src/ClkDivider.bs delete mode 100644 old_src/Deserializer.bs delete mode 100644 old_src/Serializer.bs delete mode 100644 old_src/State.bs delete mode 100644 old_src/Top.bs diff --git a/Makefile b/Makefile index e104cb8..fedfcc1 100644 --- a/Makefile +++ b/Makefile @@ -21,24 +21,13 @@ # ================================================================ # Please modify the following for your installation and setup -# Directory containing this tutorial -TUTORIAL ?= .. - -# Set this to the command that invokes your Verilog simulator -# V_SIM ?= verilator -# V_SIM ?= iverilog -# V_SIM ?= cvc -# V_SIM ?= cver -# V_SIM ?= vcsi -# V_SIM ?= vcs -# V_SIM ?= modelsim -# V_SIM ?= ncsim -# V_SIM ?= ncverilog - ifeq ($(V_SIM),verilator) V_SIM += -Xv --no-timing endif +BDPI_SRC = bdpi/uart_sim_device.c +BDPI_OBJ = bdpi/uart_sim_device.o + # ================================================================ # You should not have to change anything below this line @@ -67,6 +56,9 @@ BSC_COMP_FLAGS += \ +RTS -K128M -RTS -show-range-conflict \ $(BSC_COMP_FLAG1) $(BSC_COMP_FLAG2) $(BSC_COMP_FLAG3) +$(BDPI_OBJ): $(BDPI_SRC) + gcc -c -o $@ $< -I $(BSC_DIR)/include + BSC_LINK_FLAGS += -keep-fires BSC_PATHS = -p src/:+ @@ -112,9 +104,9 @@ b_compile: @echo Compiling for Bluesim finished .PHONY: b_link -b_link: +b_link: $(BDPI_OBJ) @echo Linking for Bluesim ... - bsc -e $(TOPMODULE) -sim -o $(B_SIM_EXE) $(B_SIM_DIRS) $(BSC_LINK_FLAGS) $(BSC_PATHS) + bsc -e $(TOPMODULE) -sim -o $(B_SIM_EXE) $(B_SIM_DIRS) $(BSC_LINK_FLAGS) $(BSC_PATHS) $(BDPI_OBJ) @echo Linking for Bluesim finished .PHONY: b_sim diff --git a/bdpi/uart_sim_device.c b/bdpi/uart_sim_device.c index 890ea6e..524b8f7 100644 --- a/bdpi/uart_sim_device.c +++ b/bdpi/uart_sim_device.c @@ -2,6 +2,22 @@ #include #include #include +#include +#include + +static volatile bool ctrl_c_received = false; + +void sigint_handler(int sig_num) { + ctrl_c_received = true; +} + +void setup_sigint_handler() { + signal(SIGINT, sigint_handler); +} + +bool was_ctrl_c_received() { + return ctrl_c_received; +} static struct termios oldt, newt; @@ -25,6 +41,11 @@ char get_char_from_terminal() { return c; } +void write_char_to_terminal(char chr) { + putchar(chr); + fflush(stdout); +} + int is_char_available() { struct timeval tv; fd_set read_fd_set; diff --git a/bram_tests/Testbench.bsv b/bram_tests/Testbench.bsv index bf35432..a074e3e 100644 --- a/bram_tests/Testbench.bsv +++ b/bram_tests/Testbench.bsv @@ -19,7 +19,7 @@ module mkTestbench(); cfg.allowWriteResponseBypass = False; // BRAM2Port#(Bit#(8), Bit#(8)) dut0 <- mkBRAM2Server(cfg); cfg.loadFormat = tagged Hex "bram2.txt"; - BRAM2Port#(Bit#(8), Bit#(8)) dut1 <- mkBRAM2Server(cfg); + BRAM1Port#(Bit#(8), Bit#(8)) dut1 <- mkBRAM1Server(cfg); rule counting; count <= count + 1; @@ -31,21 +31,21 @@ module mkTestbench(); delay(10); action $display("count = %d", count); - dut1.portB.request.put(makeRequest(False, 0, 0)); + dut1.portA.request.put(makeRequest(False, 0, 0)); endaction action $display("count = %d", count); - $display("dut1read[0] = %x", dut1.portB.response.get); - dut1.portB.request.put(makeRequest(False, 1, 0)); + $display("dut1read[0] = %x", dut1.portA.response.get); + dut1.portA.request.put(makeRequest(False, 1, 0)); endaction action $display("count = %d", count); - $display("dut1read[1] = %x", dut1.portB.response.get); - dut1.portB.request.put(makeRequest(False, 2, 0)); + $display("dut1read[1] = %x", dut1.portA.response.get); + dut1.portA.request.put(makeRequest(False, 2, 0)); endaction action $display("count = %d", count); - $display("dut1read[2] = %x", dut1.portB.response.get); + $display("dut1read[2] = %x", dut1.portA.response.get); endaction delay(100); action diff --git a/old_src/ClkDivider.bs b/old_src/ClkDivider.bs deleted file mode 100644 index 789489e..0000000 --- a/old_src/ClkDivider.bs +++ /dev/null @@ -1,40 +0,0 @@ -package ClkDivider(mkClkDivider, ClkDivider(..)) where - -interface (ClkDivider :: # -> *) hi = - { - reset :: Action - ;isAdvancing :: Bool - ;isHalfCycle :: Bool - } - -mkClkDivider :: Handle -> Module (ClkDivider hi) -mkClkDivider fileHandle = do - counter <- mkReg(0 :: UInt (TLog hi)) - let hi_value :: UInt (TLog hi) = (fromInteger $ valueOf hi) - let half_hi_value :: UInt (TLog hi) = (fromInteger $ valueOf (TDiv hi 2)) - - let val :: Real = (fromInteger $ valueOf hi) - let msg = "Clock Div Period : " + (realToString val) + "\n" - - hPutStr fileHandle msg - hPutStr fileHandle genModuleName - - addRules $ - rules - {-# ASSERT fire when enabled #-} - {-# ASSERT no implicit conditions #-} - "tick" : when True ==> action - $display (counter) - counter := if (counter == hi_value) - then 0 - else counter + 1 - - return $ - interface ClkDivider - reset :: Action - reset = do - counter := 0 - - isAdvancing :: Bool - isAdvancing = (counter == hi_value) - isHalfCycle = (counter == half_hi_value) diff --git a/old_src/Deserializer.bs b/old_src/Deserializer.bs deleted file mode 100644 index a49a419..0000000 --- a/old_src/Deserializer.bs +++ /dev/null @@ -1,53 +0,0 @@ -package Deserializer( - mkDeserialize, - IDeserializer(..), - State(..)) - where - -import ClkDivider -import State - - -interface (IDeserializer :: # -> # -> *) clkFreq baudRate = - get :: Bit 8 - putBitIn :: (Bit 1) -> Action {-# always_enabled, always_ready #-} - -mkDeserialize :: Handle -> Module (IDeserializer clkFreq baudRate) -mkDeserialize fileHandle = do - ftdiRxIn :: Wire(Bit 1) <- mkBypassWire - shiftReg :: Reg(Bit 8) <- mkReg(0) - ftdiState <- mkReg(IDLE) - - clkDivider :: (ClkDivider (TDiv clkFreq baudRate)) <- mkClkDivider fileHandle - - addRules $ - rules - - {-# ASSERT fire when enabled #-} - "IDLE" : when (ftdiState == IDLE), (ftdiRxIn == 0) ==> - do - clkDivider.reset - ftdiState := ftdiStateNext ftdiState - - {-# ASSERT fire when enabled #-} - "NOT IDLE" : when (ftdiState /= IDLE), (clkDivider.isAdvancing) ==> - do - ftdiState := ftdiStateNext ftdiState - - {-# ASSERT fire when enabled #-} - "SAMPLING" : when - DATA(n) <- ftdiState, - n >= 0, - n <= 7, - let sampleTrigger = clkDivider.isHalfCycle - in sampleTrigger - ==> - do - shiftReg := ftdiRxIn ++ shiftReg[7:1] - - return $ - interface IDeserializer - {get = shiftReg when (ftdiState == STOP), (clkDivider.isAdvancing) - ;putBitIn bit = - ftdiRxIn := bit - } \ No newline at end of file diff --git a/old_src/Serializer.bs b/old_src/Serializer.bs deleted file mode 100644 index b680a5b..0000000 --- a/old_src/Serializer.bs +++ /dev/null @@ -1,52 +0,0 @@ -package Serializer( - mkSerialize, - ISerializer(..), - State(..)) - where - -import ClkDivider -import State - -serialize :: State -> Bit 8 -> Bit 1 -serialize ftdiState dataReg = - case ftdiState of - START -> 1'b0 - (DATA n) -> dataReg[n:n] - _ -> 1'b1 - -interface (ISerializer :: # -> # -> *) clkFreq baudRate = - putBit8 :: (Bit 8) -> Action {-# always_enabled, always_ready #-} - bitLineOut :: Bit 1 {-# always_ready #-} - -mkSerialize :: Handle -> Module (ISerializer clkFreq baudRate) -mkSerialize fileHandle = do - - ftdiTxOut :: Wire(Bit 1) <- mkBypassWire - dataReg :: Reg(Bit 8) <- mkReg(0) - ftdiState <- mkReg(IDLE) - clkDivider :: (ClkDivider (TDiv clkFreq baudRate)) <- mkClkDivider fileHandle - - addRules $ - rules - {-# ASSERT fire when enabled #-} - "ADVANCE UART STATE WHEN NOT IDLE" : when - (ftdiState /= IDLE), - (clkDivider.isAdvancing) ==> - do - ftdiState := ftdiStateNext ftdiState - - {-# ASSERT fire when enabled #-} - "BIT LINE" : when True ==> - do - ftdiTxOut := serialize ftdiState dataReg - - return $ - interface ISerializer - putBit8 bit8Val = - do - clkDivider.reset - dataReg := bit8Val - ftdiState := ftdiStateNext ftdiState - when (ftdiState == IDLE) - bitLineOut = ftdiTxOut - \ No newline at end of file diff --git a/old_src/State.bs b/old_src/State.bs deleted file mode 100644 index e68a482..0000000 --- a/old_src/State.bs +++ /dev/null @@ -1,20 +0,0 @@ -package State( - State(..), - ftdiState') where - -data State = IDLE - | START - | DATA (UInt (TLog 8)) - | PARITY - | STOP - deriving (Bits, Eq, FShow) - -ftdiState' :: State -> State -ftdiState' state = - case state of - IDLE -> START - START -> DATA(0) - DATA(7) -> PARITY - DATA(n) -> DATA(n+1) - PARITY -> STOP - STOP -> IDLE \ No newline at end of file diff --git a/old_src/Top.bs b/old_src/Top.bs deleted file mode 100644 index de93692..0000000 --- a/old_src/Top.bs +++ /dev/null @@ -1,56 +0,0 @@ --- TOPMODULE=mkTop make b_compile -package Top(mkTop, ITop(..), mkSim) where - -import Deserializer -import Serializer - -type FCLK = 25_000_000 -type BAUD = 9_600 - -interface ITop = - ftdi_rxd :: Bit 1 {-# always_ready #-} - led :: Bit 8 {-# always_ready #-} - ftdi_txd :: (Bit 1) -> Action {-# always_enabled, always_ready #-} - -{-# properties mkTop={verilog} #-} -mkTop :: Module (ITop) -mkTop = do - - fileHandle <- openFile "compile.log" WriteMode - - deserializer :: (IDeserializer FCLK BAUD) <- mkDeserialize fileHandle - serializer :: (ISerializer FCLK BAUD) <- mkSerialize fileHandle - ftdiBitIn :: Wire(Bit 1) <- mkBypassWire - rxReg :: Reg(Bit 8) <- mkReg(0) - messageM $ "Hallo!!" + (realToString 5) - - addRules $ - rules - when True ==> - do - rxReg := deserializer.get - serializer.putBit8 $ deserializer.get - - when True ==> - deserializer.putBitIn ftdiBitIn - - return $ - interface ITop - {ftdi_rxd = serializer.bitLineOut - ;led = rxReg - ;ftdi_txd bitIn = ftdiBitIn := bitIn} - -mkSim :: Module Empty -mkSim = do - -- count :: Reg(UInt 3) <- mkReg(0) - count :: Reg(UInt 3) <- mkReg(0) - addRules $ - rules - "count" : when True ==> action - count := unpack ((1'b1) ++ (pack count)[2:1]) - $display count - "end sim" : when (count == 6) ==> action - $finish - - return $ - interface Empty \ No newline at end of file diff --git a/src/Core.bsv b/src/Core.bsv index a23c679..46a244e 100644 --- a/src/Core.bsv +++ b/src/Core.bsv @@ -1,5 +1,8 @@ package Core; +import ClkDivider::*; +import Prelude::*; + interface Core#(numeric type clkFreq); method Bit#(8) get_char(); method Bit#(8) get_led(); @@ -7,13 +10,31 @@ interface Core#(numeric type clkFreq); endinterface module mkCore(Core#(clkFreq)); - Wire#(Bit#(8)) uart_out <- mkWire; + // Reg # (UInt # (32)) counter <- mkReg(0); + Reg # (UInt # (TLog # (clkFreq))) counter <- mkReg(0); + Wire # (Bool) tick_second <- mkDWire(False); + Wire # (Bit # (8)) uart_out <- mkWire; + Reg # (Bit # (8)) led_out <- mkReg(0); + + Integer clkFreqInt = valueOf(clkFreq); + UInt#(TLog#(clkFreq)) clkFreqUInt = fromInteger(clkFreqInt); + Real val = fromInteger(clkFreqInt); + messageM("mkCore clkFreq" + realToString(val)); + + rule second_counter; + counter <= (counter == clkFreqUInt) ? 0 : counter + 1; + tick_second <= True; + endrule + + rule update_led(tick_second); + led_out <= led_out + 1; + endrule method Bit#(8) get_char(); return uart_out; endmethod method Bit#(8) get_led(); - return uart_out; + return led_out; endmethod method Action put_char(Bit#(8) byte_in); uart_out <= byte_in; diff --git a/src/Top.bsv b/src/Top.bsv index d31e353..0a95dbe 100644 --- a/src/Top.bsv +++ b/src/Top.bsv @@ -5,6 +5,15 @@ export ITop(..); // export mkSim; +import "BDPI" function Action init_terminal(); +import "BDPI" function Action restore_terminal(); +import "BDPI" function Bit#(8) get_char_from_terminal(); +import "BDPI" function Int#(32) is_char_available(); +import "BDPI" function Action write_char_to_terminal(Bit#(8) chr); + +import "BDPI" function Action setup_sigint_handler(); +import "BDPI" function Bool was_ctrl_c_received(); + import Deserializer::*; import Core::*; import Serializer::*; @@ -29,46 +38,59 @@ module mkTop(ITop); ISerializer # (FCLK, BAUD) serializer <- mkSerialize(fileHandle); Core # (FCLK) core <- mkCore(); - Reg#(Bit#(8)) ledReg <- mkReg(0); + Reg#(Bit#(8)) persist_led <- mkReg(0); messageM("Hallo!!" + realToString(5)); - rule attach_core_outputs; - ledReg <= core.get_led; + // connect up core device + rule core_led_o; + persist_led <= core.get_led; + endrule + rule core_char_device_o; serializer.putBit8(core.get_char); endrule - - rule attach_core_inputs; + rule core_char_device_i; core.put_char(deserializer.get); endrule + // output methods method Bit#(1) ftdi_rxd; return serializer.bitLineOut; endmethod - method Bit#(8) led; - return ledReg; - endmethod - method Action ftdi_txd(Bit#(1) bitIn); deserializer.putBitIn(bitIn); endmethod + method Bit#(8) led; + return persist_led; + endmethod endmodule module mkSim(Empty); BRAM_Configure cfg = defaultValue; // Define a 3-bit register named count - Reg#(UInt#(3)) count <- mkReg(0); + Reg#(UInt#(3)) count <- mkReg(0); + Reg#(Bool) init_C_functions <- mkReg(False); + Core#(FCLK) core <- mkCore(); - // Rule to update and display the count - rule tick (True); - count <= unpack({1'b1, (pack(count))[2:1]}); - ($display)(count); + rule init_c_functions_once (!init_C_functions); + init_terminal(); + setup_sigint_handler(); + init_C_functions <= True; + endrule + + rule core_char_device_o; + write_char_to_terminal(core.get_char); + endrule + rule core_char_device_i(is_char_available() == 1); + core.put_char(get_char_from_terminal()); endrule // Rule to finish the simulation when count reaches 6 - rule end_sim (count == 6); + rule end_sim (was_ctrl_c_received()); + restore_terminal(); + $display("GOT CTRL+C"); ($finish)(); endrule endmodule