Skip to content

Commit

Permalink
feat: convert CW_t*
Browse files Browse the repository at this point in the history
Closes #24
  • Loading branch information
SingularityKChen committed Aug 4, 2023
1 parent 802eaad commit b3042ee
Show file tree
Hide file tree
Showing 6 changed files with 463 additions and 0 deletions.
105 changes: 105 additions & 0 deletions chipware/src/CW_tap.scala
Original file line number Diff line number Diff line change
@@ -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())
})
}
127 changes: 127 additions & 0 deletions chipware/src/CW_tap_uc.scala
Original file line number Diff line number Diff line change
@@ -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<sup>(width)</sup>)-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
})
}
43 changes: 43 additions & 0 deletions chipware/src/CW_thermdec.scala
Original file line number Diff line number Diff line change
@@ -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 | 2<sup>width</sup> | 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))
})
}
69 changes: 69 additions & 0 deletions chipware/test/src/utest/tap.scala
Original file line number Diff line number Diff line change
@@ -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)
)
}
}
}
Loading

0 comments on commit b3042ee

Please sign in to comment.