How to make a simple core for CSR bus
From Milkymist Wiki
There is AVNET Spartan 3 Evaluation board that will be used for learning purposes, for this board there is fork of the Milkymist SoC with basic core functionality: (This example need to be ported to the Milkymist One Board)
Bus data is fixed at 32bits, remenber that !
* LM32 Processor * CRS Bus * GPIO * UART * 16kbits On Chip Ram (2 KBytes)
In the milkymist-avnet directory you'll find two interesting folders:
cores <- source code of the system modules, you can find both rtl and doc folder for each one boards/avnet-sp3aevl <- related to the synthesis and core setup for specific board
Especially the file:
Points the included sources for the system, so you should consider add the new folders here, appending this:
And fix last line as follow (note new directory is included):
CORES_SRC=$(CONBUS_SRC) $(LM32_SRC) $(CSRBRG_SRC) $(NORFLASH_SRC) $(BRAM_SRC) $(UART_SRC) $(SYSCTL_SRC) $(COUNTER)
Before continue is good idea create a git branch so you can make sure what you change later using commits or even merging code with master branch, run thisy:
git checkout -b counter
Try make sure git know what changed and or new files added using:
git add <filename>
and when you selected all the files that would be part of the commit, that’s for the end all the tutorial when we got the new feature working :)
For the first edited file:
git add boards/avnet-sp3aevl/sources.mak
Remember do same for others.
This assume also you created the new directory.
Now create new folders:
mkdir cores/counter mkdir cores/counter/rtl mkdir cores/counter/doc
Then simply do:
git commit -m "commit message"
Now is time to start coding new core template, before i suggest keep in mind file:
Later we will need to add some lines there according to the core features.
New core file:
This core is intended to be simple as possible, mainly it is re-used code from the sysctl core for the GPIO input and CSR bus.
The counter have a single external clock input which is need to be synced with then Milkymist clock, to avoid Clock Domain Crossing Issues.
You can read more information in fpg4fun about how to implement a solution in verilog.
The counter code diff is here:
Check module in/out defintion
Input is defined:
Now adding the counter core to the system editing:
This requires a bit more of editing, check code here:
Take look close to:
* GPIO * CSR Bus * WISHBONE to CSR bridge (For OR part check CSR bus topology)
The big part is from line 522, in wich:
* some parameters are filled with real values * core is linked to CSR * core input pin is linked to physical pin defined in the UCF file
Assign FPGA pins for external input editing file:
With the new content:
NET "count(0)" LOC = E13 | IOSTANDARD = LVCMOS33;