diff --git a/scripts/Murax/iCE40-hx8k_breakout_board_xip/Makefile b/scripts/Murax/iCE40-hx8k_breakout_board_xip/Makefile new file mode 100644 index 0000000..309e0df --- /dev/null +++ b/scripts/Murax/iCE40-hx8k_breakout_board_xip/Makefile @@ -0,0 +1,38 @@ + + +VERILOG = ../../../Murax.v toplevel.v + +generate : + #(cd ../../..; sbt "run-main vexriscv.demo.MuraxWithXip") + +../../../Murax.v : + #(cd ../../..; sbt "run-main vexriscv.demo.MuraxWithXip") + +../../../Murax.v*.bin: + +bin/toplevel.blif : ${VERILOG} ../../../Murax.v*.bin + mkdir -p bin + rm -f Murax.v*.bin + cp ../../../Murax.v*.bin . | true + yosys -v3 -p "synth_ice40 -top toplevel -blif bin/toplevel.blif" ${VERILOG} + +bin/toplevel.asc : toplevel.pcf bin/toplevel.blif + arachne-pnr -p toplevel.pcf -d 8k --max-passes 600 -P ct256 bin/toplevel.blif -o bin/toplevel.asc + +bin/toplevel.bin : bin/toplevel.asc + icepack bin/toplevel.asc bin/toplevel.bin + +compile : bin/toplevel.bin + +time: bin/toplevel.bin + icetime -tmd hx8k bin/toplevel.asc + +prog : bin/toplevel.bin + iceprog -S bin/toplevel.bin + +sudo-prog : bin/toplevel.bin + sudo iceprog -S bin/toplevel.bin + +clean : + rm -rf bin + rm -f Murax.v*.bin diff --git a/scripts/Murax/iCE40-hx8k_breakout_board_xip/README.md b/scripts/Murax/iCE40-hx8k_breakout_board_xip/README.md new file mode 100644 index 0000000..62078a3 --- /dev/null +++ b/scripts/Murax/iCE40-hx8k_breakout_board_xip/README.md @@ -0,0 +1,84 @@ +This example is for the +[Lattice iCE40HX-8K Breakout Board](http://www.latticesemi.com/Products/DevelopmentBoardsAndKits/iCE40HX8KBreakoutBoard.aspx). + +An image of this board is shown below; +![img/iCE40HX8K-breakout-revA.png] + +This board can be purchased for ~$USD 49 directly from Lattice and is supported +by the IceStorm +[`iceprog`](https://github.com/cliffordwolf/icestorm/tree/master/iceprog) tool. + + +# Using the example + +## Before Starting + +Before starting make sure that your board is configured for `CRAM Programming` +mode. This requires removing jumper `J7` and putting the pair of jumpers on +`J6` to be parallel to the text on the board. + +This is shown in **Figure 5** of the +[iCE40HX-8K Breakout Board User Guide](http://www.latticesemi.com/view_document?document_id=50373). +which is also reproduced below; +![img/cram-programming-config.png] + +Once your board is ready, you should follow the setup instructions at the +[top level](../../../README.md). + +You should make sure you have the following tools installed; + * Yosys + * arachne-pnr + * icestorm tools (like icepack and iceprog) + * riscv toolchain + * sbt + +## Building + +You should be able to just type `make compile` and get output similar to this; +``` +... + place time 10.14s +route... + pass 1, 15 shared. + pass 2, 4 shared. + pass 3, 1 shared. + pass 4, 0 shared. + +After routing: +span_4 4406 / 29696 +span_12 951 / 5632 + + route time 9.12s +write_txt bin/toplevel.asc... +icepack bin/toplevel.asc bin/toplevel.bin +``` + +The process should take around 30 seconds on a reasonable fast computer. + +## Programming + +After building you should be able to run `make prog`. You may need to run `make +sudo-prog` if root is needed to access your USB devices. + +You should get output like the following; +``` +iceprog -S bin/toplevel.bin +init.. +cdone: high +reset.. +cdone: low +programming.. +cdone: high +Bye. +``` + +After programming the LEDs at the top of the board should start flashing in an +interesting pattern. + +## Connect + +After programming you should be able to connect to the serial port and have the +output echoed back to you. + +On Linux you can do this using a command like `screen /dev/ttyUSB1`. Then as +you type you should get back the same characters. diff --git a/scripts/Murax/iCE40-hx8k_breakout_board_xip/img/cram-programming-config.png b/scripts/Murax/iCE40-hx8k_breakout_board_xip/img/cram-programming-config.png new file mode 100644 index 0000000..48562bb Binary files /dev/null and b/scripts/Murax/iCE40-hx8k_breakout_board_xip/img/cram-programming-config.png differ diff --git a/scripts/Murax/iCE40-hx8k_breakout_board_xip/img/iCE40HX8K-breakout-revA.png b/scripts/Murax/iCE40-hx8k_breakout_board_xip/img/iCE40HX8K-breakout-revA.png new file mode 100644 index 0000000..2c460bb Binary files /dev/null and b/scripts/Murax/iCE40-hx8k_breakout_board_xip/img/iCE40HX8K-breakout-revA.png differ diff --git a/scripts/Murax/iCE40-hx8k_breakout_board_xip/toplevel.pcf b/scripts/Murax/iCE40-hx8k_breakout_board_xip/toplevel.pcf new file mode 100644 index 0000000..4962e25 --- /dev/null +++ b/scripts/Murax/iCE40-hx8k_breakout_board_xip/toplevel.pcf @@ -0,0 +1,23 @@ +## iCE40-hx8k breakout board + +set_io io_J3 J3 +set_io io_H16 H16 +set_io io_G15 G15 +set_io io_G16 G16 +set_io io_F15 F15 +set_io io_B12 B12 +set_io io_B10 B10 +set_io io_led[0] B5 +set_io io_led[1] B4 +set_io io_led[2] A2 +set_io io_led[3] A1 +set_io io_led[4] C5 +set_io io_led[5] C4 +set_io io_led[6] B3 +set_io io_led[7] C3 + +#XIP +set_io io_P12 P12 +set_io io_P11 P11 +set_io io_R11 R11 +set_io io_R12 R12 \ No newline at end of file diff --git a/scripts/Murax/iCE40-hx8k_breakout_board_xip/toplevel.v b/scripts/Murax/iCE40-hx8k_breakout_board_xip/toplevel.v new file mode 100644 index 0000000..db884cc --- /dev/null +++ b/scripts/Murax/iCE40-hx8k_breakout_board_xip/toplevel.v @@ -0,0 +1,76 @@ +`timescale 1ns / 1ps + +module toplevel( + input io_J3, + input io_H16, + input io_G15, + output io_G16, + input io_F15, + output io_B12, + input io_B10, + + input io_P12, + output io_P11, + output io_R11, + output io_R12, + + output [7:0] io_led + + ); + + wire [31:0] io_gpioA_read; + wire [31:0] io_gpioA_write; + wire [31:0] io_gpioA_writeEnable; + wire io_mainClk; + wire io_jtag_tck; + + SB_GB mainClkBuffer ( + .USER_SIGNAL_TO_GLOBAL_BUFFER (io_J3), + .GLOBAL_BUFFER_OUTPUT ( io_mainClk) + ); + + SB_GB jtagClkBuffer ( + .USER_SIGNAL_TO_GLOBAL_BUFFER (io_H16), + .GLOBAL_BUFFER_OUTPUT ( io_jtag_tck) + ); + + assign io_led = io_gpioA_write[7 : 0]; + + + wire [1:0] io_xpi_sclk_write; + wire io_xpi_data_0_writeEnable; + wire [1:0] io_xpi_data_0_read; + wire [1:0] io_xpi_data_0_write; + wire io_xpi_data_1_writeEnable; + wire [1:0] io_xpi_data_1_read; + wire [1:0] io_xpi_data_1_write; + wire [0:0] io_xpi_ss; + + assign io_P11 = io_xpi_data_0_write[0]; + assign io_xpi_data_1_read[0] = io_P12; + assign io_xpi_data_1_read[1] = io_P12; + assign io_R11 = io_xpi_sclk_write[0]; + assign io_R12 = io_xpi_ss[0]; + + Murax murax ( + .io_asyncReset(0), + .io_mainClk (io_mainClk ), + .io_jtag_tck(io_jtag_tck), + .io_jtag_tdi(io_G15), + .io_jtag_tdo(io_G16), + .io_jtag_tms(io_F15), + .io_gpioA_read (io_gpioA_read), + .io_gpioA_write (io_gpioA_write), + .io_gpioA_writeEnable(io_gpioA_writeEnable), + .io_uart_txd(io_B12), + .io_uart_rxd(io_B10), + .io_xpi_sclk_write(io_xpi_sclk_write), + .io_xpi_data_0_writeEnable(io_xpi_data_0_writeEnable), + .io_xpi_data_0_read(io_xpi_data_0_read), + .io_xpi_data_0_write(io_xpi_data_0_write), + .io_xpi_data_1_writeEnable(io_xpi_data_1_writeEnable), + .io_xpi_data_1_read(io_xpi_data_1_read), + .io_xpi_data_1_write(io_xpi_data_1_write), + .io_xpi_ss(io_xpi_ss) + ); +endmodule \ No newline at end of file diff --git a/src/main/scala/vexriscv/demo/Murax.scala b/src/main/scala/vexriscv/demo/Murax.scala index aac654f..df82e83 100644 --- a/src/main/scala/vexriscv/demo/Murax.scala +++ b/src/main/scala/vexriscv/demo/Murax.scala @@ -45,7 +45,7 @@ case class MuraxConfig(coreFrequency : HertzNumber, val genXpi = xipConfig != null def addXip(): MuraxConfig = copy(xipConfig = SpiDdrMasterCtrl.MemoryMappingParameters( - SpiDdrMasterCtrl.Parameters(8, 12, SpiDdrParameter(4, 1)).addAllMods(), + SpiDdrMasterCtrl.Parameters(8, 12, SpiDdrParameter(2, 1)).addAllMods(), cmdFifoDepth = 32, rspFifoDepth = 32, xip = SpiDdrMasterCtrl.XipBusParameters(addressWidth = 24, dataWidth = 32) diff --git a/src/test/scala/vexriscv/MuraxSim.scala b/src/test/scala/vexriscv/MuraxSim.scala index 46131cd..4d65b63 100644 --- a/src/test/scala/vexriscv/MuraxSim.scala +++ b/src/test/scala/vexriscv/MuraxSim.scala @@ -20,8 +20,8 @@ import scala.collection.mutable object MuraxSim { def main(args: Array[String]): Unit = { // def config = MuraxConfig.default.copy(onChipRamSize = 256 kB) - def config = MuraxConfig.default.copy(onChipRamSize = 4 kB, onChipRamHexFile = "src/main/ressource/hex/muraxDemo.hex") - + def config = MuraxConfig.default.copy(onChipRamSize = 4 kB, onChipRamHexFile = "src/main/ressource/hex/muraxDemo.hex").addXip() + val simSlowDown = true SimConfig.allOptimisation.withWave.compile(new Murax(config)).doSimUntilVoid{dut => val mainClkPeriod = (1e12/dut.config.coreFrequency.toDouble).toLong val jtagClkPeriod = mainClkPeriod*4 @@ -47,6 +47,7 @@ object MuraxSim { baudPeriod = uartBaudPeriod ) + if(config.xipConfig != null)dut.io.xpi.data(1).read #= 0 val guiThread = fork{ val guiToSim = mutable.Queue[Any]() @@ -101,6 +102,7 @@ object MuraxSim { dut.io.gpioA.read #= (dut.io.gpioA.write.toLong & dut.io.gpioA.writeEnable.toLong) | (switchValue() << 8) ledsValue = dut.io.gpioA.write.toLong ledsFrame.repaint() + if(simSlowDown) Thread.sleep(400) } } }