From c3c2cd53e1bb4d3c2c04ee43dd18227aa89dbaa8 Mon Sep 17 00:00:00 2001 From: Yehowshua Immanuel Date: Tue, 26 Sep 2023 00:40:04 -0400 Subject: [PATCH] working towards sim uart-like device support --- bdpi/uart_sim_device.c | 53 +++++++++++++++++++++++++++++++++++++ bram_tests/Testbench.bsv | 56 ++++++++++++++++++++++++++++++++++++++++ bram_tests/bram2.txt | 4 +++ src/Core.bsv | 23 +++++++++++++++++ src/Serializer.bsv | 2 +- src/Top.bsv | 34 ++++++++++++------------ 6 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 bdpi/uart_sim_device.c create mode 100644 bram_tests/Testbench.bsv create mode 100644 bram_tests/bram2.txt create mode 100644 src/Core.bsv diff --git a/bdpi/uart_sim_device.c b/bdpi/uart_sim_device.c new file mode 100644 index 0000000..890ea6e --- /dev/null +++ b/bdpi/uart_sim_device.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include + +static struct termios oldt, newt; + +void init_terminal() { + // Get terminal attributes + tcgetattr(STDIN_FILENO, &oldt); + newt = oldt; + + // Set terminal to raw mode (no echo, non-canonical) + newt.c_lflag &= ~(ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &newt); +} + +void restore_terminal() { + // Restore terminal to its old state + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); +} + +char get_char_from_terminal() { + char c = getchar(); + return c; +} + +int is_char_available() { + struct timeval tv; + fd_set read_fd_set; + + // Don't wait at all, not even a microsecond + tv.tv_sec = 0; + tv.tv_usec = 0; + + // Watch stdin (fd 0) to see when it has input + FD_ZERO(&read_fd_set); + FD_SET(0, &read_fd_set); + + // Check if there's any input available + if (select(1, &read_fd_set, NULL, NULL, &tv) == -1) { + perror("select"); + return 0; // 0 indicates no characters available + } + + if (FD_ISSET(0, &read_fd_set)) { + // Character is available + return 1; + } else { + // No character available + return 0; + } +} \ No newline at end of file diff --git a/bram_tests/Testbench.bsv b/bram_tests/Testbench.bsv new file mode 100644 index 0000000..bf35432 --- /dev/null +++ b/bram_tests/Testbench.bsv @@ -0,0 +1,56 @@ +// bsc -sim -u -g mkTestbench Testbench.bsv; bsc -sim -e mkTestbench -o simBRAM; ./simBRAM -V +import BRAM::*; +import StmtFSM::*; +import Clocks::*; + +function BRAMRequest#(Bit#(8), Bit#(8)) makeRequest(Bool write, Bit#(8) addr, Bit#(8) data); + return BRAMRequest{ + write: write, + responseOnWrite:False, + address: addr, + datain: data + }; +endfunction + +(* synthesize *) +module mkTestbench(); + Reg#(UInt#(3)) count <- mkReg(0); + BRAM_Configure cfg = defaultValue; + 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); + + rule counting; + count <= count + 1; + endrule + + //Define StmtFSM to run tests + Stmt test = + (seq + delay(10); + action + $display("count = %d", count); + dut1.portB.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)); + endaction + action + $display("count = %d", count); + $display("dut1read[1] = %x", dut1.portB.response.get); + dut1.portB.request.put(makeRequest(False, 2, 0)); + endaction + action + $display("count = %d", count); + $display("dut1read[2] = %x", dut1.portB.response.get); + endaction + delay(100); + action + $finish(); + endaction + endseq); + mkAutoFSM(test); +endmodule \ No newline at end of file diff --git a/bram_tests/bram2.txt b/bram_tests/bram2.txt new file mode 100644 index 0000000..46c17c1 --- /dev/null +++ b/bram_tests/bram2.txt @@ -0,0 +1,4 @@ +fe +ed +f0 +0d \ No newline at end of file diff --git a/src/Core.bsv b/src/Core.bsv new file mode 100644 index 0000000..a23c679 --- /dev/null +++ b/src/Core.bsv @@ -0,0 +1,23 @@ +package Core; + +interface Core#(numeric type clkFreq); + method Bit#(8) get_char(); + method Bit#(8) get_led(); + method Action put_char(Bit#(8) byte_in); +endinterface + +module mkCore(Core#(clkFreq)); + Wire#(Bit#(8)) uart_out <- mkWire; + + method Bit#(8) get_char(); + return uart_out; + endmethod + method Bit#(8) get_led(); + return uart_out; + endmethod + method Action put_char(Bit#(8) byte_in); + uart_out <= byte_in; + endmethod +endmodule + +endpackage \ No newline at end of file diff --git a/src/Serializer.bsv b/src/Serializer.bsv index 2b507cf..3a82572 100644 --- a/src/Serializer.bsv +++ b/src/Serializer.bsv @@ -23,7 +23,7 @@ interface ISerializer#(numeric type clkFreq, numeric type baudRate); endinterface module mkSerialize#(Handle fileHandle)(ISerializer#(clkFreq, baudRate)); - Wire#(Bit#(1)) ftdiTxOut <- mkBypassWire(); + Wire#(Bit#(1)) ftdiTxOut <- mkDWire(1); Reg#(Bit#(8)) dataReg <- mkReg(0); Reg#(State) ftdiState <- mkReg(IDLE); diff --git a/src/Top.bsv b/src/Top.bsv index a7faa70..0a14f03 100644 --- a/src/Top.bsv +++ b/src/Top.bsv @@ -6,40 +6,40 @@ export ITop(..); // export mkSim; import Deserializer::*; - +import Core::*; import Serializer::*; +import BRAM::*; typedef 25000000 FCLK; - typedef 9600 BAUD; interface ITop; (* always_ready *) - method Bit#(1) ftdi_rxd(); + method Bit # (1) ftdi_rxd(); (* always_ready *) - method Bit#(8) led(); + method Bit # (8) led(); (* always_enabled , always_ready *) method Action ftdi_txd(Bit#(1) bitIn); -endinterface: ITop +endinterface (* synthesize *) module mkTop(ITop); Handle fileHandle <- openFile("compile.log", WriteMode); - IDeserializer#(FCLK, BAUD) deserializer <- mkDeserialize(fileHandle); - ISerializer#(FCLK, BAUD) serializer <- mkSerialize(fileHandle); + IDeserializer # (FCLK, BAUD) deserializer <- mkDeserialize(fileHandle); + ISerializer # (FCLK, BAUD) serializer <- mkSerialize(fileHandle); + Core # (FCLK) core <- mkCore(); - Wire#(Bit#(1)) ftdiBitIn <- mkBypassWire; - Reg#(Bit#(8)) rxReg <- mkReg(0); + Reg#(Bit#(8)) ledReg <- mkReg(0); messageM("Hallo!!" + realToString(5)); - rule loopback; - rxReg <= deserializer.get; - serializer.putBit8(deserializer.get); + rule attach_core_outputs; + ledReg <= core.get_led; + serializer.putBit8(core.get_char); endrule - rule txOut; - deserializer.putBitIn(ftdiBitIn); + rule attach_core_inputs; + core.put_char(deserializer.get); endrule method Bit#(1) ftdi_rxd; @@ -47,15 +47,16 @@ module mkTop(ITop); endmethod method Bit#(8) led; - return rxReg; + return ledReg; endmethod method Action ftdi_txd(Bit#(1) bitIn); - ftdiBitIn <= bitIn; + deserializer.putBitIn(bitIn); endmethod endmodule module mkSim(Empty); + BRAM_Configure cfg = defaultValue; // Define a 3-bit register named count Reg#(UInt#(3)) count <- mkReg(0); @@ -70,7 +71,6 @@ module mkSim(Empty); rule end_sim (count == 6); ($finish)(); endrule - endmodule