diff --git a/src/main/scala/ee/hrzn/chryse/platform/ice40/ICE40Top.scala b/src/main/scala/ee/hrzn/chryse/platform/ice40/ICE40Top.scala index 43d80ab..cc03b96 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/ice40/ICE40Top.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/ice40/ICE40Top.scala @@ -22,8 +22,8 @@ class ICE40Top[Top <: Module]( private val clki = Wire(Clock()) - private val clk_gb = Module(new SB_GB) - clk_gb.USER_SIGNAL_TO_GLOBAL_BUFFER := clki + private val clk_gb = Module(new SB_GB_IO) + clk_gb.PACKAGE_PIN := clki private val clk = clk_gb.GLOBAL_BUFFER_OUTPUT private val timerLimit = (15e-6 * platform.clockHz).toInt diff --git a/src/main/scala/ee/hrzn/chryse/platform/ice40/IOStandard.scala b/src/main/scala/ee/hrzn/chryse/platform/ice40/IOStandard.scala new file mode 100644 index 0000000..2be88ea --- /dev/null +++ b/src/main/scala/ee/hrzn/chryse/platform/ice40/IOStandard.scala @@ -0,0 +1,5 @@ +package ee.hrzn.chryse.platform.ice40 + +object IOStandard { + val LV_CMOS = "SB_LVCMOS" +} diff --git a/src/main/scala/ee/hrzn/chryse/platform/ice40/IceBreakerPlatform.scala b/src/main/scala/ee/hrzn/chryse/platform/ice40/IceBreakerPlatform.scala index 54a0188..71643ae 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/ice40/IceBreakerPlatform.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/ice40/IceBreakerPlatform.scala @@ -24,7 +24,7 @@ final case class IceBreakerPlatform(ubtnReset: Boolean = false) } class IceBreakerPlatformResources extends PlatformBoardResources { - // TODO: IO_STANDARD=SB_LVCMOS needs to be set on most. + // TODO: IO_STANDARD=SB_LVCMOS needs to be set on most SB_IOs. val clock = resource.ClockSource(12_000_000).onPin(35) val ubtn = resource.Button().inverted.onPin(10) diff --git a/src/main/scala/ee/hrzn/chryse/platform/ice40/PinType.scala b/src/main/scala/ee/hrzn/chryse/platform/ice40/PinType.scala new file mode 100644 index 0000000..048b414 --- /dev/null +++ b/src/main/scala/ee/hrzn/chryse/platform/ice40/PinType.scala @@ -0,0 +1,10 @@ +package ee.hrzn.chryse.platform.ice40 + +// See SiliconBlue ICEā„¢ Technology Library. +object PinType { + val PIN_INPUT = 0x1 + + val PIN_NO_OUTPUT = 0x0 + val PIN_OUTPUT = 0x18 + val PIN_OUTPUT_TRISTATE = 0x28 +} diff --git a/src/main/scala/ee/hrzn/chryse/platform/ice40/SB_GB.scala b/src/main/scala/ee/hrzn/chryse/platform/ice40/SB_GB.scala deleted file mode 100644 index 26725b1..0000000 --- a/src/main/scala/ee/hrzn/chryse/platform/ice40/SB_GB.scala +++ /dev/null @@ -1,9 +0,0 @@ -package ee.hrzn.chryse.platform.ice40 - -import chisel3._ -import chisel3.experimental.ExtModule - -class SB_GB extends ExtModule { - val USER_SIGNAL_TO_GLOBAL_BUFFER = IO(Input(Clock())) - val GLOBAL_BUFFER_OUTPUT = IO(Output(Clock())) -} diff --git a/src/main/scala/ee/hrzn/chryse/platform/ice40/SB_GB_IO.scala b/src/main/scala/ee/hrzn/chryse/platform/ice40/SB_GB_IO.scala new file mode 100644 index 0000000..2cb0797 --- /dev/null +++ b/src/main/scala/ee/hrzn/chryse/platform/ice40/SB_GB_IO.scala @@ -0,0 +1,15 @@ +package ee.hrzn.chryse.platform.ice40 + +import chisel3._ +import chisel3.experimental.ExtModule + +class SB_GB_IO(pinType: Int = (PinType.PIN_INPUT | PinType.PIN_NO_OUTPUT)) + extends ExtModule( + Map( + "IO_STANDARD" -> IOStandard.LV_CMOS, + "PIN_TYPE" -> pinType, + ), + ) { + val PACKAGE_PIN = IO(Input(Clock())) + val GLOBAL_BUFFER_OUTPUT = IO(Output(Clock())) +} diff --git a/src/main/scala/ee/hrzn/chryse/platform/ice40/SB_IO.scala b/src/main/scala/ee/hrzn/chryse/platform/ice40/SB_IO.scala new file mode 100644 index 0000000..60743f4 --- /dev/null +++ b/src/main/scala/ee/hrzn/chryse/platform/ice40/SB_IO.scala @@ -0,0 +1,32 @@ +package ee.hrzn.chryse.platform.ice40 + +import chisel3._ +import chisel3.experimental.Analog +import chisel3.experimental.ExtModule + +class SB_IO( + pinType: Int, + ioStandard: String = IOStandard.LV_CMOS, + pullup: Boolean = false, +) extends ExtModule( + Map( + "IO_STANDARD" -> ioStandard, + "PIN_TYPE" -> pinType, + "PULLUP" -> (if (pullup) 1 else 0), + ), + ) { + + private def genPin(): Data = { + if (pinType == PinType.PIN_INPUT) + Input(Bool()) + else if (pinType == PinType.PIN_OUTPUT) + Output(Bool()) + else if (pinType == (PinType.PIN_INPUT | PinType.PIN_OUTPUT_TRISTATE)) + Analog(1.W) + else + throw new IllegalArgumentException(s"unhandled pinType: $pinType") + + } + val PACKAGE_PIN = IO(genPin()) + val GLOBAL_BUFFER_OUTPUT = IO(genPin()) +}