Freedom on arty s7 - port in progress but need some help please

I am working to port freedom e300 to the arty s7 , so far i have been able to change what I think is necessary, xdc and tcl config files, only thing is a problem with QSPI clock . On Arty, freedom uses the additional pin connection to QSPI clock pin to drive the clock , this is not possible on Arty S7.
I have done a few attempts described here
https://github.com/sifive/freedom/issues/46

but still not been able to boot, and actually I have some timing problems.

Does someone from freedom experts tell me what am I missing please.

Wil lappreciate your support,

Hi,
I can’t help you with the freedom RTL specificly because I‘m not familiar with it. But to access the SPI clk signal on the Arty S7 you must instantiate the Xilinx “startupe2” primitive in the verilog code. This allows access to the configuration clock. I haven’t tried it on my own yet, but to my understanding you must connect the spi clk output of the freedom RTL to the usrcclk0 input of the primitive.

Alternatively you can buy a PmodSF3 from Digilent and connect it to some of the pmod connectors. The SF3 contains a SPI flash chip similar to the one soldered on the board but you will have complete control over it. Of course it is not a out-of-the-box solution, but it may be a good starting point. You only need to adapt the xdc file to connect to the Pmod.

Thomas

Hello @thornschuh

Thank you for comments,

I have tried to connect the RTL clock, but perhaps I am not too familiar on how RTL and scala works, I have a verilog code attempt here that does

.USRCCLKO(sck)

but then how I am suppose to connect the clock from E300 processor?

What I think is correct is to replace the line

val qspi_sck = IO(Analog(1.W))

with

val qspi_sck = Wire(Clock())

Then assign it value on ArtyShell.scala using

val ip_qspi_sck = Module(new qspi_sck_bridge)
qspi_sck := ip_qspi_sck.io.sck

I am not really sure since FPGAchip.scala (under src/main/scala/everywhere/e300artydevkit/)
also assign a value in line 47 like this

IOBUF(qspi_sck, dut.io.pins.qspi.sck)

the last line I have commented.

I think the PMOD is a good idea, unfortunately I don’t have one at hand.

Please let me know of anything you might see here wrong.

Hi, @mhanuel

I have ported freedom e300 to Nexys4DDR.

I faced same problem. I wrote Chisel code to instantiate STARTUPE2 as following.

class STARTUPE2 extends BlackBox {
  val io = new Bundle {
    val CLK = Input(Bool())
    val GSR = Input(Bool())
    val GTS = Input(Bool())
    val KEYCLEARB = Input(Bool())
    val PACK = Input(Bool())
    val USRCCLKO = Input(Bool())
    val USRCCLKTS = Input(Bool())
    val USRDONEO = Input(Bool())
    val USRDONETS = Input(Bool())
  }
}

object STARTUPE2 {

  def apply(usrcclk0: Bool) = {
    val startupe2 = Module(new STARTUPE2)
    startupe2.io.CLK := false.B
    startupe2.io.GSR := false.B
    startupe2.io.GTS := false.B
    startupe2.io.KEYCLEARB := false.B
    startupe2.io.PACK := false.B
    startupe2.io.USRCCLKO := usrcclk0
    startupe2.io.USRCCLKTS := false.B
    startupe2.io.USRDONEO := true.B
    startupe2.io.USRDONETS := true.B

    startupe2
  }
}

Above code committed in fpga-shells/src/main/scala/ip/xilinx/Xilinx.scala

And then, I connected it to “dut.io.pins.qspi.sck.o.oval” as following in fpga-shells/src/main/scala/ip/xilinx/Xilinx.scala

  withClockAndReset(clock_32MHz, ~ck_rst) {
    val dut = Module(new E300Nexys4DDRDevKitPlatform)

    //---------------------------------------------------------------------
    // SPI flash IOBUFs
    //---------------------------------------------------------------------

    STARTUPE2(dut.io.pins.qspi.sck.o.oval)
    IOBUF(qspi_cs,  dut.io.pins.qspi.cs(0))