Last active
August 29, 2015 14:21
-
-
Save cr1901/4bd3a99872b3b3ff6a01 to your computer and use it in GitHub Desktop.
Mercury MiGen Initial Attempt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`ifdef LM32_CONFIG_V | |
`else | |
`define LM32_CONFIG_V | |
// | |
// EXCEPTION VECTORS BASE ADDRESS | |
// | |
// Base address for exception vectors | |
`define CFG_EBA_RESET 32'h00000000 | |
// Base address for the debug exception vectors. If the DC_RE flag is | |
// set or the at_debug signal is asserted (see CFG_ALTERNATE_EBA) this | |
// will also be used for normal exception vectors. | |
`define CFG_DEBA_RESET 32'h10000000 | |
// Enable exception vector remapping by external signal | |
//`define CFG_ALTERNATE_EBA | |
// | |
// ALU OPTIONS | |
// | |
// Enable sign-extension instructions | |
`define CFG_SIGN_EXTEND_ENABLED | |
// Shifter | |
// You may either enable the piplined or the multi-cycle barrel | |
// shifter. The multi-cycle shifter will stall the pipeline until | |
// the result is available after 32 cycles. | |
// If both options are disabled, only "right shift by one bit" is | |
// available. | |
`define CFG_MC_BARREL_SHIFT_ENABLED | |
//`define CFG_PL_BARREL_SHIFT_ENABLED | |
// Multiplier | |
// The multiplier is available either in a multi-cycle version or | |
// in a pipelined one. The multi-cycle multiplier stalls the pipe | |
// for 32 cycles. If both options are disabled, multiply operations | |
// are not supported. | |
`define CFG_MC_MULTIPLY_ENABLED | |
//`define CFG_PL_MULTIPLY_ENABLED | |
// Enable the multi-cycle divider. Stalls the pipe until the result | |
// is ready after 32 cycles. If disabled, the divide operation is not | |
// supported. | |
`define CFG_MC_DIVIDE_ENABLED | |
// | |
// INTERRUPTS | |
// | |
// Enable support for 32 hardware interrupts | |
`define CFG_INTERRUPTS_ENABLED | |
// Enable level-sensitive interrupts. The interrupt line status is | |
// reflected in the IP register, which is then read-only. | |
//`define CFG_LEVEL_SENSITIVE_INTERRUPTS | |
// | |
// USER INSTRUCTION | |
// | |
// Enable support for the user opcode. | |
//`define CFG_USER_ENABLED | |
// | |
// MEMORY MANAGEMENT UNIT | |
// | |
// Enable instruction and data translation lookaside buffers and | |
// restricted user mode. | |
//`define CFG_MMU_ENABLED | |
// | |
// CACHE | |
// | |
// Instruction cache | |
`define CFG_ICACHE_ENABLED | |
`define CFG_ICACHE_ASSOCIATIVITY 1 | |
`define CFG_ICACHE_SETS 128 | |
`define CFG_ICACHE_BYTES_PER_LINE 4 | |
`define CFG_ICACHE_BASE_ADDRESS 32'h00000000 | |
`define CFG_ICACHE_LIMIT 32'h7fffffff | |
// Data cache | |
`define CFG_DCACHE_ENABLED | |
`define CFG_DCACHE_ASSOCIATIVITY 1 | |
`define CFG_DCACHE_SETS 128 | |
`define CFG_DCACHE_BYTES_PER_LINE 4 | |
`define CFG_DCACHE_BASE_ADDRESS 32'h00000000 | |
`define CFG_DCACHE_LIMIT 32'h7fffffff | |
// | |
// DEBUG OPTION | |
// | |
// Globally enable debugging | |
//`define CFG_DEBUG_ENABLED | |
// Enable the hardware JTAG debugging interface. | |
// Note: to use this, there must be a special JTAG module for your | |
// device. At the moment, there is only support for the | |
// Spartan-6. | |
//`define CFG_JTAG_ENABLED | |
// JTAG UART is a communication channel which uses JTAG to transmit | |
// and receive bytes to and from the host computer. | |
//`define CFG_JTAG_UART_ENABLED | |
// Enable reading and writing to the memory and writing CSRs using | |
// the JTAG interface. | |
//`define CFG_HW_DEBUG_ENABLED | |
// Number of hardware watchpoints, max. 4 | |
//`define CFG_WATCHPOINTS 32'h4 | |
// Enable hardware breakpoints | |
//`define CFG_ROM_DEBUG_ENABLED | |
// Number of hardware breakpoints, max. 4 | |
//`define CFG_BREAKPOINTS 32'h4 | |
// Put the processor into debug mode by an external signal. That is, | |
// raise a breakpoint exception. This is useful if you have a debug | |
// monitor and a serial line and you want to trap into the monitor on a | |
// BREAK symbol on the serial line. | |
//`define CFG_EXTERNAL_BREAK_ENABLED | |
// | |
// REGISTER FILE | |
// | |
// The following option explicitly infers block RAM for the register | |
// file. There is extra logic to avoid parallel writes and reads. | |
// Normally, if your synthesizer is smart enough, this should not be | |
// necessary because it will automatically infer block RAM for you. | |
//`define CFG_EBR_POSEDGE_REGISTER_FILE | |
// Explicitly infers block RAM, too. But it uses two different clocks, | |
// one being shifted by 180deg, for the read and write port. Therefore, | |
// no additional logic to avoid the parallel write/reads. | |
//`define CFG_EBR_NEGEDGE_REGISTER_FILE | |
// | |
// MISCELLANEOUS | |
// | |
// Exceptions on wishbone bus errors | |
//`define CFG_BUS_ERRORS_ENABLED | |
// Enable the cycle counter | |
`define CFG_CYCLE_COUNTER_ENABLED | |
// Embedded instruction ROM using on-chip block RAM | |
//`define CFG_IROM_ENABLED | |
//`define CFG_IROM_INIT_FILE "NONE" | |
//`define CFG_IROM_BASE_ADDRESS 32'h10000000 | |
//`define CFG_IROM_LIMIT 32'h10000fff | |
// Embedded data RAM using on-chip block RAM | |
//`define CFG_DRAM_ENABLED | |
//`define CFG_DRAM_INIT_FILE "NONE" | |
//`define CFG_DRAM_BASE_ADDRESS 32'h20000000 | |
//`define CFG_DRAM_LIMIT 32'h20000fff | |
// Trace unit | |
//`define CFG_TRACE_ENABLED | |
// Resolve unconditional branches already in the X stage (UNTESTED!) | |
//`define CFG_FAST_UNCONDITIONAL_BRANCH | |
// log2 function | |
// If your simulator/synthesizer does not support the $clog2 system | |
// function you can use a constant function instead. | |
function integer clog2; | |
input integer value; | |
begin | |
value = value - 1; | |
for (clog2 = 0; value > 0; clog2 = clog2 + 1) | |
value = value >> 1; | |
end | |
endfunction | |
`define CLOG2 clog2 | |
//`define CLOG2 $clog2 | |
`endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This file is Copyright (c) 2015 William D. Jones <[email protected]> | |
# License: BSD | |
from mibuild.generic_platform import * | |
from mibuild.xilinx import XilinxPlatform | |
from mibuild.xilinx.programmer import XC3SProg | |
_io = [ | |
("clk", 0, Pins("P43"), IOStandard("LVCMOS33")), | |
("user_led", 0, Pins("P13"), IOStandard("LVTTL")), | |
("user_led", 1, Pins("P15"), IOStandard("LVTTL")), | |
("user_led", 2, Pins("P16"), IOStandard("LVTTL")), | |
("user_led", 3, Pins("P19"), IOStandard("LVTTL")), | |
("user_btn", 0, Pins("P41"), IOStandard("LVTTL")), | |
#The serial port is in fact over SPI. The creators of the board provide a VHDL | |
#file for talking over this interface. In light of space constraints and the fact | |
#that both the FT245RL and FPGA can BOTH be SPI primaries, however, | |
#It may be necessary to sacrifice two "high-speed" (DIO, INPIN) pins instead. | |
("serial", 0, | |
Subsignal("tx", Pins("P20"), IOStandard("LVCMOS33")), # FTDI D1 | |
Subsignal("rx", Pins("P68"), IOStandard("LVCMOS33")) # FTDI D0 | |
), | |
#The FPGA is simultaneously an SPI primary and secondary! | |
#FPGA is secondary... | |
#("spiserial", 0, | |
# #Subsignal("fpga_prog", Pins("V3"), IOStandard("LVTTL")) | |
# Subsignal("fpga_csn", Pins("P39"), IOStandard("LVTTL")), | |
# Subsignal("clk", Pins("P53"), IOStandard("LVTTL")), | |
# Subsignal("mosi", Pins("P46"), IOStandard("LVTTL")), | |
# Subsignal("miso", Pins("P51"), IOStandard("LVTTL")) | |
# ), | |
#FPGA is primary... | |
("spiflash", 0, | |
Subsignal("flash_csn", Pins("P27"), IOStandard("LVTTL")), | |
Subsignal("clk", Pins("P53"), IOStandard("LVTTL")), | |
Subsignal("mosi", Pins("P46"), IOStandard("LVTTL")), | |
Subsignal("miso", Pins("P51"), IOStandard("LVTTL")) | |
), | |
("spiflash2x", 0, | |
Subsignal("cs_n", Pins("P27")), | |
Subsignal("clk", Pins("P53")), | |
Subsignal("dq", Pins("P46", "P51")), | |
IOStandard("LVTTL"), Misc("SLEW=FAST") | |
), | |
#SRAM and 5V-tolerant I/O share a parallel bus. The SRAM controller needs | |
#to take care of switching the bus between the two. | |
("sram", 0, | |
Subsignal("a", Pins("P59 P60 P61 P62 P64 P57 P56 P52 P50 P49 P85 P84" | |
"P83 P78 P77 P65 P70 P71 P72 P73")), #A19 is actually unused. | |
Subsignal("d", Pins("P5 P4 P6 P98 P94 P93 P90 P89")), #8-bit data bus | |
Subsignal("we_n", Pins("P88")), | |
#Subsignal("oe_n", Pins()), #If OE wasn't tied to ground on Mercury, this pin would be here. | |
Subsignal("ce_n", Pins("P59")), #Memory chip-enable. Called MEM_CEN in schematic. | |
Subsignal("bussw_oe_n", Pins("P60")), #Mercury-specific. 5V tolerant GPIO is shared w/ memory using this pin. | |
IOStandard("LVTTL"), Misc("SLEW=FAST") | |
), | |
#ADC over SPI- FPGA is primary | |
("adc", 0, | |
Subsignal("cs_n", Pins("P21"), IOStandard("LVTTL")), | |
Subsignal("clk", Pins("P10"), IOStandard("LVTTL")), | |
Subsignal("mosi", Pins("P9" ), IOStandard("LVTTL")), | |
Subsignal("miso", Pins("P12"), IOStandard("LVTTL")) | |
) | |
] | |
#Perhaps define some connectors as having a specific purpose- i.e. a 5V GPIO bus | |
#with data, peripheral-select, and control signals? | |
_connectors = [ | |
("IO", "P59 P60 P61 P62 P64 P57 P56 P52 P50 P49 P85 P84 P83 P78 P77 P65 P70" | |
"P71 P72 P73 P5 P4 P6 P98 P94 P93 P90 P89 P88 P86"), #5V I/O | |
("DIO", "P20 P32 P33 P34 P35 P36 P37"), #Fast 3.3V IO (Directly attached to FPGA) | |
("CIO", "P40 P44"), #Clock IO | |
("INPIN", "P68 P97 P7 P82") #Input-only pins | |
] | |
class Platform(XilinxPlatform): | |
default_clk_name = "clk" | |
default_clk_period = 20 | |
def __init__(self, device="xc3s200a-4-vq100", programmer="xc3sprog"): | |
self.programmer = programmer | |
XilinxPlatform.__init__(self, device, _io, _connectors) | |
#Small device- optimize for AREA instead of speed (LM32 runs at about | |
#65MHz in AREA configuration). | |
self.toolchain.xst_opt = self.toolchain.xst_opt.replace("SPEED", "AREA") | |
def create_programmer(self): | |
#Not actually supported right now- I need to add FT245RL support to xc3sprog. | |
if self.programmer == "xc3sprog": | |
return XC3SProg("mercury", "bscan_spi_mercury.bit") | |
else: | |
raise ValueError("{} programmer is not supported".format(programmer)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from migen.fhdl.std import * | |
from migen.bus import wishbone | |
from migen.genlib.io import CRG | |
from misoclib.soc import SoC, mem_decoder | |
from misoclib.mem.flash import spiflash | |
class BaseSoC(SoC): | |
default_platform = "mercury" | |
#Required, or will error out. | |
csr_map = { | |
"spiflash": 16, | |
} | |
csr_map.update(SoC.csr_map) | |
def __init__(self, platform, **kwargs): | |
SoC.__init__(self, platform, | |
clk_freq=int((1/(platform.default_clk_period))*1000000000), | |
#integrated_rom_size=0x4000, #Still may use embedded ROM using | |
#distributed RAM instead of spiflash, so FPGA is free to be SPi | |
#secondary. | |
integrated_main_ram_size=0, | |
integrated_sram_size=512, #SRAM should be moved out of here into | |
#the controller, but we error out if sram_size is 0. | |
#with_uart = False, #Compilation will fail (Mercury does not have a proper UART). | |
#with_identifier = False, #Compilation will fail | |
**kwargs) | |
self.submodules.crg = CRG(platform.request(platform.default_clk_name)) | |
self.submodules.spiflash = spiflash.SpiFlash(platform.request("spiflash2x"), | |
dummy=10, div=2) | |
self.flash_boot_address = 0x180000 | |
self.register_rom(self.spiflash.bus) | |
#self.register_rom(self.spiflash.bus, 0x1000000) | |
#TODO- add SRAM controller | |
default_subtarget = BaseSoC |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment