diff --git a/chipware/src/CW_tap.scala b/chipware/src/CW_tap.scala
new file mode 100644
index 0000000..3d9aa6a
--- /dev/null
+++ b/chipware/src/CW_tap.scala
@@ -0,0 +1,105 @@
+import chisel3._
+import chisel3.experimental._
+import chisel3.util._
+
+/**
+ * == CW_tap ==
+ *
+ * === Abstract ===
+ *
+ * TAP Controller
+ *
+ * === Parameters ===
+ *
+ * | Parameter | Legal Range | Default | Description |
+ * |------------|--------------|----------|--------------|
+ * | width | 2 to 32 | 2 | Width of instruction register |
+ * | id | 0 or 1 | 0 | Determines whether the device identification register is present. 0 = not present, 1 = present |
+ * | version | 0 to 15 | 0 | 4-bit version number |
+ * | part | 0 to 65535 | 0 | 16-bit part number |
+ * | man_num | 0 to 2047, man_num !=127 | 0 | 11-bit JEDEC manufacturer identity code |
+ * | sync_mode | 0 or 1 | 0 | Determines whether the bypass, device identification, and instruction registers are synchronous with respect to tck. 0 = asynchronous, 1 = synchronous |
+ *
+ * === Ports ===
+ *
+ * | Name | Width | Direction | Description |
+ * |----------------|--------------|-----------|--------------|
+ * | tck | 1 bit | Input | Test clock |
+ * | trst_n | 1 bit | Input | Test reset, active low |
+ * | tms | 1 bit | Input | Test mode select |
+ * | tdi | 1 bit | Input | Test data in |
+ * | so | 1 bit | Input | Serial data from boundary scan registers and data registers |
+ * | bypass_sel | 1 bit | Input | Selects bypass register, active high |
+ * | sentinel_val | width-1 bit(s) | Input | User defined status bits |
+ * | clock_dr | 1 bit | Output | Clock's in data in asynchronous mode |
+ * | shift_dr | 1 bit | Output | Enables shifting of data in both synchronous and asynchronous mode |
+ * | update_dr | 1 bit | Output | Enables updating data in asynchronous mode |
+ * | tdo | 1 bit | Output | Test data out |
+ * | tdo_en | 1 bit | Output | Enables for tdo output buffer |
+ * | tap_state | 16 bits | Output | Current state of the TAP finite state machine |
+ * | extest | 1 bit | Output | EXTEST decoded instruction |
+ * | samp_load | 1 bit | Output | SAMPLE/PRELOAD decoded instruction |
+ * | instructions | width bit(s) | Output | Instruction register output |
+ * | sync_capture_en | 1 bit | Output | Enable for synchronous capture |
+ * | sync_update_dr | 1 bit | Output | Enable updating new data in |
+ * | test | 1 bit | Input | For scannable designs, the test_mode pin is held active (HIGH) during testing. For normal operation , it is held inactive (LOW) |
+ *
+ * @param width Width of instruction register
+ * @param id Determines whether the device identification register is present. 0 = not present, 1 = present
+ * @param version 4-bit version number
+ * @param part 16-bit part number
+ * @param man_num 11-bit JEDEC manufacturer identity code
+ * @param sync_mode Determines whether the bypass, device identification, and instruction registers are synchronous with respect to tck. 0 = asynchronous, 1 = synchronous
+ */
+class CW_tap(
+ val width: Int = 2,
+ val id: Int = 0,
+ val version: Int = 0,
+ val part: Int = 0,
+ val man_num: Int = 0,
+ val sync_mode: Int = 0)
+ extends BlackBox(
+ Map(
+ "width" -> width,
+ "id" -> id,
+ "version" -> version,
+ "part" -> part,
+ "man_num" -> man_num,
+ "sync_mode" -> sync_mode
+ )
+ )
+ with HasBlackBoxPath {
+ // Validation of all parameters
+ require(width >= 2 && width <= 32, "width must be in the range [2, 32]")
+ require(id == 0 || id == 1, "id must be 0 or 1")
+ require(version >= 0 && version <= 15, "version must be in the range [0, 15]")
+ require(part >= 0 && part <= 65535, "part must be in the range [0, 65535]")
+ require(
+ man_num >= 0 && man_num <= 2047 && man_num != 127,
+ "man_num must be in the range [0, 2047] and not equal to 127"
+ )
+ require(sync_mode == 0 || sync_mode == 1, "sync_mode must be 0 or 1")
+
+ // Define ports with type annotations
+ val io = IO(new Bundle {
+ val tck: Clock = Input(Clock())
+ val trst_n: Bool = Input(Bool())
+ val tms: Bool = Input(Bool())
+ val tdi: Bool = Input(Bool())
+ val so: Bool = Input(Bool())
+ val bypass_sel: Bool = Input(Bool())
+ val sentinel_val: UInt = Input(UInt((width - 1).W))
+ val clock_dr: Bool = Output(Bool())
+ val shift_dr: Bool = Output(Bool())
+ val update_dr: Bool = Output(Bool())
+ val tdo: Bool = Output(Bool())
+ val tdo_en: Bool = Output(Bool())
+ val tap_state: UInt = Output(UInt(16.W))
+ val extest: Bool = Output(Bool())
+ val samp_load: Bool = Output(Bool())
+ val instructions: UInt = Output(UInt(width.W))
+ val sync_capture_en: Bool = Output(Bool())
+ val sync_update_dr: Bool = Output(Bool())
+ val test: Bool = Input(Bool())
+ })
+}
diff --git a/chipware/src/CW_tap_uc.scala b/chipware/src/CW_tap_uc.scala
new file mode 100644
index 0000000..9310cdc
--- /dev/null
+++ b/chipware/src/CW_tap_uc.scala
@@ -0,0 +1,127 @@
+import chisel3._
+import chisel3.util._
+import chisel3.experimental._
+
+/**
+ * == CW_tap_uc ==
+ *
+ * === Abstract ===
+ *
+ * TAP Controller with Usercode support.
+ *
+ * === Parameters ===
+ *
+ * | Parameter | Legal Range | Default | Description |
+ * |----------------|------------------------------|----------|-----------------------------------------|
+ * | width | 2 to 32 | 2 | Width of instruction register |
+ * | id | 0 or 1 | 0 | Determines presence of ID register |
+ * | idcode_opcode | 1 to ((2(width))-1) | 1 | Opcode for IDCODE instruction |
+ * | version | 0 to 15 | 0 | 4-bit version number |
+ * | part | 0 to 65535 | 0 | 16-bit part number |
+ * | man_num | 0 to 2047, man_num != 127 | 0 | 11-bit JEDEC manufacturer identity code|
+ * | sync_mode | 0 or 1 | 0 | Synchronous mode for registers |
+ * | tst_mode | 0 or 1 | 0 | Test pin control |
+ *
+ * === Ports ===
+ *
+ * | Name | Width | Direction | Description |
+ * |----------------|------------------------------|-----------|-----------------------------------------|
+ * | tck | 1 bit | Input | Test clock |
+ * | trst_n | 1 bit | Input | Test reset, active low |
+ * | tms | 1 bit | Input | Test mode select |
+ * | tdi | 1 bit | Input | Test data in |
+ * | so | 1 bit | Input | Serial data from boundary scan registers and data registers |
+ * | bypass_sel | 1 bit | Input | Selects bypass register, active high |
+ * | sentinel_val | width - 2 (s) bits | Input | User defined status bits |
+ * | ver_sel | 1 bit | Input | Selects version from parameter or ver input port |
+ * | device_id_sel | 1 bit | Input | Selects device identification register, active high |
+ * | user_code_sel | 1 bit | Input | Selects user_code_val bus for input into device identification register, active high |
+ * | user_code_val | 32 bits | Input | 32-bit user defined code |
+ * | ver | 4 bits | Input | 4-bit version number |
+ * | part_num | 16 bits | Input | 16-bit part number |
+ * | part_num_sel | 1 bit | Input | Selects part from parameter or part_num from input port |
+ * | mnfr_id | 11 bits | Input | 11-bit JEDEC manufacturer's identity code (mnfr_id != 127) |
+ * | mnfr_id_sel | 1 bit | Input | Selects man_num from parameter or mnfr_id from input port |
+ * | test | 1 bit | Input | Scantest enable pin, NOT used in CW |
+ * | clock_dr | 1 bit | Output | Clock's in data in asynchronous mode |
+ * | shift_dr | 1 bit | Output | Enables shifting of data in both synchronous and asynchronous mode |
+ * | update_dr | 1 bit | Output | Enables updating data in asynchronous mode |
+ * | tdo | 1 bit | Output | Test data out |
+ * | tdo_en | 1 bit | Output | Enables for tdo output buffer |
+ * | tap_state | 16 bits | Output | Current state of the TAP finite state machine |
+ * | instructions | width bit(s) | Output | Instruction register output |
+ * | sync_capture_en | 1 bit | Output | Enable for synchronous capture |
+ * | sync_update_dr | 1 bit | Output | Enable updating new data in synchronous mode |
+ *
+ * @param width Width of instruction register
+ * @param id Determines presence of ID register
+ * @param idcode_opcode Opcode for IDCODE instruction
+ * @param version 4-bit version number
+ * @param part 16-bit part number
+ * @param man_num 11-bit JEDEC manufacturer identity code
+ * @param sync_mode Synchronous mode for registers
+ * @param tst_mode Test pin control
+ */
+class CW_tap_uc(
+ val width: Int = 2,
+ val id: Int = 0,
+ val idcode_opcode: Int = 1,
+ val version: Int = 0,
+ val part: Int = 0,
+ val man_num: Int = 0,
+ val sync_mode: Int = 0,
+ val tst_mode: Int = 0)
+ extends BlackBox(
+ Map(
+ "width" -> width,
+ "id" -> id,
+ "idcode_opcode" -> idcode_opcode,
+ "version" -> version,
+ "part" -> part,
+ "man_num" -> man_num,
+ "sync_mode" -> sync_mode,
+ "tst_mode" -> tst_mode
+ )
+ )
+ with HasBlackBoxPath {
+ // Add validations for parameters
+ require(width >= 2 && width <= 32, "width must be between 2 and 32")
+ require(id == 0 || id == 1, "id must be 0 or 1")
+ require(idcode_opcode >= 1 && idcode_opcode < Math.pow(2, width), "idcode_opcode out of range")
+ require(version >= 0 && version <= 15, "version must be between 0 and 15")
+ require(part >= 0 && part <= 65535, "part must be between 0 and 65535")
+ require(man_num >= 0 && man_num <= 2047 && man_num != 127, "man_num must be between 0 and 2047 (excluding 127)")
+ require(sync_mode == 0 || sync_mode == 1, "sync_mode must be 0 or 1")
+ require(tst_mode == 0 || tst_mode == 1, "tst_mode must be 0 or 1")
+
+ // Define ports with type annotations
+ val io = IO(new Bundle {
+ val tck: Bool = Input(Bool()) // Test clock
+ val trst_n: Bool = Input(Bool()) // Test reset, active low
+ val tms: Bool = Input(Bool()) // Test mode select
+ val tdi: Bool = Input(Bool()) // Test data in
+ val so: Bool = Input(Bool()) // Serial data from boundary scan registers and data registers
+ val bypass_sel: Bool = Input(Bool()) // Selects bypass register, active high
+ val sentinel_val: UInt = Input(UInt((width - 2).W)) // User defined status bits
+ val ver_sel: Bool = Input(Bool()) // Selects version from parameter or ver input port
+ val device_id_sel: Bool = Input(Bool()) // Selects device identification register, active high
+ val user_code_sel: Bool =
+ Input(Bool()) // Selects user_code_val bus for input into device identification register, active high
+ val user_code_val: UInt = Input(UInt(32.W)) // 32-bit user defined code
+ val ver: UInt = Input(UInt(4.W)) // 4-bit version number
+ val part_num: UInt = Input(UInt(16.W)) // 16-bit part number
+ val part_num_sel: Bool = Input(Bool()) // Selects part from parameter or part_num from input port
+ val mnfr_id: UInt = Input(UInt(11.W)) // 11-bit JEDEC manufacturer's identity code (mnfr_id != 127)
+ val mnfr_id_sel: Bool = Input(Bool()) // Selects man_num from parameter or mnfr_id from input port
+ val test: Bool = Input(Bool()) // Scantest enable pin, NOT used in CW
+ val clock_dr: Bool = Output(Bool()) // Clock's in data in asynchronous mode
+ val shift_dr: Bool = Output(Bool()) // Enables shifting of data in both synchronous and asynchronous mode
+ val update_dr: Bool = Output(Bool()) // Enables updating data in asynchronous mode
+ val tdo: Bool = Output(Bool()) // Test data out
+ val tdo_en: Bool = Output(Bool()) // Enables for tdo output buffer
+ val tap_state: UInt = Output(UInt(16.W)) // Current state of the TAP finite state machine
+ val instructions: UInt = Output(UInt(width.W)) // Instruction register output
+ val sync_capture_en: Bool = Output(Bool()) // Enable for synchronous capture
+ val sync_update_dr: Bool = Output(Bool()) // Enable updating new data in synchronous mode
+ })
+}
diff --git a/chipware/src/CW_thermdec.scala b/chipware/src/CW_thermdec.scala
new file mode 100644
index 0000000..f3772d4
--- /dev/null
+++ b/chipware/src/CW_thermdec.scala
@@ -0,0 +1,43 @@
+import chisel3._
+import chisel3.experimental._
+import chisel3.util._
+
+/**
+ * == CW_thermdec ==
+ *
+ * === Abstract ===
+ *
+ * Decoder
+ *
+ * === Parameters ===
+ *
+ * | Parameter | Legal Range | Default | Description |
+ * |---------------|--------------|--------------|----------------|
+ * | width | 1 to 16 | 3 | Bit width of input a |
+ *
+ * === Ports ===
+ *
+ * | Name | Width | Direction | Description |
+ * |--------|--------------|-----------|------------------------|
+ * | en | 1 | Input | Enable input (active high) |
+ * | a | width | Input | Binary Input |
+ * | b | 2width | Output | Decode output |
+ * @param width Bit width of input a
+ */
+class CW_thermdec(val width: Int = 3)
+ extends BlackBox(
+ Map(
+ "width" -> width
+ )
+ )
+ with HasBlackBoxPath {
+ // Validation of width parameter
+ require(width >= 1 && width <= 16, "width must be in the range [1, 16]")
+
+ // Define ports with type annotations
+ val io = IO(new Bundle {
+ val en: Bool = Input(Bool())
+ val a: UInt = Input(UInt(width.W))
+ val b: UInt = Output(UInt((1 << width).W))
+ })
+}
diff --git a/chipware/test/src/utest/tap.scala b/chipware/test/src/utest/tap.scala
new file mode 100644
index 0000000..39f5a46
--- /dev/null
+++ b/chipware/test/src/utest/tap.scala
@@ -0,0 +1,69 @@
+import chisel3._
+import circt.stage._
+import utest._
+
+class tap(
+ val width: Int = 2,
+ val id: Int = 0,
+ val version: Int = 0,
+ val part: Int = 0,
+ val man_num: Int = 0,
+ val sync_mode: Int = 0)
+ extends RawModule {
+ val io = IO(new Bundle {
+ val tck: Clock = Input(Clock())
+ val trst_n: Bool = Input(Bool())
+ val tms: Bool = Input(Bool())
+ val tdi: Bool = Input(Bool())
+ val so: Bool = Input(Bool())
+ val bypass_sel: Bool = Input(Bool())
+ val sentinel_val: UInt = Input(UInt((width - 1).W))
+ val clock_dr: Bool = Output(Bool())
+ val shift_dr: Bool = Output(Bool())
+ val update_dr: Bool = Output(Bool())
+ val tdo: Bool = Output(Bool())
+ val tdo_en: Bool = Output(Bool())
+ val tap_state: UInt = Output(UInt(16.W))
+ val extest: Bool = Output(Bool())
+ val samp_load: Bool = Output(Bool())
+ val instructions: UInt = Output(UInt(width.W))
+ val sync_capture_en: Bool = Output(Bool())
+ val sync_update_dr: Bool = Output(Bool())
+ val test: Bool = Input(Bool())
+ })
+
+ protected val U1: CW_tap = Module(new CW_tap(width, id, version, part, man_num, sync_mode))
+ U1.io.tck := io.tck
+ U1.io.trst_n := io.trst_n
+ U1.io.tms := io.tms
+ U1.io.tdi := io.tdi
+ U1.io.so := io.so
+ U1.io.bypass_sel := io.bypass_sel
+ U1.io.sentinel_val := io.sentinel_val
+ U1.io.test := io.test
+ io.clock_dr := U1.io.clock_dr
+ io.shift_dr := U1.io.shift_dr
+ io.update_dr := U1.io.update_dr
+ io.tdo := U1.io.tdo
+ io.tdo_en := U1.io.tdo_en
+ io.tap_state := U1.io.tap_state
+ io.extest := U1.io.extest
+ io.samp_load := U1.io.samp_load
+ io.instructions := U1.io.instructions
+ io.sync_capture_en := U1.io.sync_capture_en
+ io.sync_update_dr := U1.io.sync_update_dr
+}
+
+object tap extends TestSuite {
+ val tests: Tests = Tests {
+ test("should instantiate tapTester") {
+ def top = new tap(2, 0, 0, 0, 0, 0)
+
+ val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
+ (new ChiselStage).execute(
+ args = Array("--target-dir", "./build"),
+ annotations = generator :+ CIRCTTargetAnnotation(CIRCTTarget.SystemVerilog)
+ )
+ }
+ }
+}
diff --git a/chipware/test/src/utest/tap_uc.scala b/chipware/test/src/utest/tap_uc.scala
new file mode 100644
index 0000000..2ac65a4
--- /dev/null
+++ b/chipware/test/src/utest/tap_uc.scala
@@ -0,0 +1,89 @@
+import chisel3._
+import circt.stage._
+import utest._
+
+class tap_uc(
+ val width: Int = 2,
+ val id: Int = 0,
+ val idcode_opcode: Int = 1,
+ val version: Int = 0,
+ val part: Int = 0,
+ val man_num: Int = 0,
+ val sync_mode: Int = 0,
+ val tst_mode: Int = 0)
+ extends RawModule {
+ val io = IO(new Bundle {
+ val tck: Bool = Input(Bool()) // Test clock
+ val trst_n: Bool = Input(Bool()) // Test reset, active low
+ val tms: Bool = Input(Bool()) // Test mode select
+ val tdi: Bool = Input(Bool()) // Test data in
+ val so: Bool = Input(Bool()) // Serial data from boundary scan registers and data registers
+ val bypass_sel: Bool = Input(Bool()) // Selects bypass register, active high
+ val sentinel_val: UInt = Input(UInt((width - 2).W)) // User defined status bits
+ val ver_sel: Bool = Input(Bool()) // Selects version from parameter or ver input port
+ val device_id_sel: Bool = Input(Bool()) // Selects device identification register, active high
+ val user_code_sel: Bool =
+ Input(Bool()) // Selects user_code_val bus for input into device identification register, active high
+ val user_code_val: UInt = Input(UInt(32.W)) // 32-bit user defined code
+ val ver: UInt = Input(UInt(4.W)) // 4-bit version number
+ val part_num: UInt = Input(UInt(16.W)) // 16-bit part number
+ val part_num_sel: Bool = Input(Bool()) // Selects part from parameter or part_num from input port
+ val mnfr_id: UInt = Input(UInt(11.W)) // 11-bit JEDEC manufacturer's identity code (mnfr_id != 127)
+ val mnfr_id_sel: Bool = Input(Bool()) // Selects man_num from parameter or mnfr_id from input port
+ val test: Bool = Input(Bool()) // Scantest enable pin, NOT used in CW
+ val clock_dr: Bool = Output(Bool()) // Clock's in data in asynchronous mode
+ val shift_dr: Bool = Output(Bool()) // Enables shifting of data in both synchronous and asynchronous mode
+ val update_dr: Bool = Output(Bool()) // Enables updating data in asynchronous mode
+ val tdo: Bool = Output(Bool()) // Test data out
+ val tdo_en: Bool = Output(Bool()) // Enables for tdo output buffer
+ val tap_state: UInt = Output(UInt(16.W)) // Current state of the TAP finite state machine
+ val instructions: UInt = Output(UInt(width.W)) // Instruction register output
+ val sync_capture_en: Bool = Output(Bool()) // Enable for synchronous capture
+ val sync_update_dr: Bool = Output(Bool()) // Enable updating new data in synchronous mode
+ })
+
+ // Define the BlackBox instantiation
+ protected val U1: CW_tap_uc = Module(
+ new CW_tap_uc(width, id, idcode_opcode, version, part, man_num, sync_mode, tst_mode)
+ )
+ U1.io.tck := io.tck
+ U1.io.trst_n := io.trst_n
+ U1.io.tms := io.tms
+ U1.io.tdi := io.tdi
+ U1.io.so := io.so
+ U1.io.bypass_sel := io.bypass_sel
+ U1.io.sentinel_val := io.sentinel_val
+ U1.io.ver_sel := io.ver_sel
+ U1.io.device_id_sel := io.device_id_sel
+ U1.io.user_code_sel := io.user_code_sel
+ U1.io.user_code_val := io.user_code_val
+ U1.io.ver := io.ver
+ U1.io.part_num := io.part_num
+ U1.io.part_num_sel := io.part_num_sel
+ U1.io.mnfr_id := io.mnfr_id
+ U1.io.mnfr_id_sel := io.mnfr_id_sel
+ U1.io.test := io.test
+ io.clock_dr := U1.io.clock_dr
+ io.shift_dr := U1.io.shift_dr
+ io.update_dr := U1.io.update_dr
+ io.tdo := U1.io.tdo
+ io.tdo_en := U1.io.tdo_en
+ io.tap_state := U1.io.tap_state
+ io.instructions := U1.io.instructions
+ io.sync_capture_en := U1.io.sync_capture_en
+ io.sync_update_dr := U1.io.sync_update_dr
+}
+
+object tap_uc extends TestSuite {
+ val tests: Tests = Tests {
+ test("should instantiate tap_uc") {
+ def top = new tap_uc(2, 1, 1, 0, 0, 0, 0, 0)
+
+ val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
+ (new ChiselStage).execute(
+ args = Array("--target-dir", "./build"),
+ annotations = generator :+ CIRCTTargetAnnotation(CIRCTTarget.SystemVerilog)
+ )
+ }
+ }
+}
diff --git a/chipware/test/src/utest/thermdec.scala b/chipware/test/src/utest/thermdec.scala
new file mode 100644
index 0000000..3ec57b5
--- /dev/null
+++ b/chipware/test/src/utest/thermdec.scala
@@ -0,0 +1,30 @@
+import chisel3._
+import circt.stage._
+import utest._
+
+class thermdec(val width: Int = 3) extends RawModule {
+ val io = IO(new Bundle {
+ val en: Bool = Input(Bool())
+ val a: UInt = Input(UInt(width.W))
+ val b: UInt = Output(UInt((1 << width).W))
+ })
+
+ protected val U1: CW_thermdec = Module(new CW_thermdec(width))
+ U1.io.en := io.en
+ U1.io.a := io.a
+ io.b := U1.io.b
+}
+
+object thermdec extends TestSuite {
+ val tests: Tests = Tests {
+ test("should instantiate thermdec") {
+ def top = new thermdec(3)
+
+ val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
+ (new ChiselStage).execute(
+ args = Array("--target-dir", "./build"),
+ annotations = generator :+ CIRCTTargetAnnotation(CIRCTTarget.SystemVerilog)
+ )
+ }
+ }
+}