Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- # This file is Copyright (c) 2019 Antti Lukats <[email protected]>
- # This file is Copyright (c) 2019 msloniewski <[email protected]>
- # License: BSD
- import argparse
- from migen import *
- from litex_boards.partner.platforms import max1000
- from litex.soc.integration.soc_core import *
- from litex.soc.integration.soc_sdram import *
- from litex.soc.integration.builder import *
- from litedram.modules import MT48LC4M16
- from litedram.phy import GENSDRPHY
- from litex.soc.cores import gpio
- from litex.soc.cores.spi_flash import SpiFlash
- class VgaOutputGenerator(Module):
- def __init__(self, pads, clk):
- self.clock_domains.cd_clk = ClockDomain()
- self.comb += self.cd_clk.clk.eq(clk)
- WIDTH = 640
- HEIGHT = 480
- BIT_DEPTH = 8
- ADDRESS_WIDTH = 32
- # VGA output
- self.pixel = pixel = Signal(24)
- self.vga_hsync = vga_hsync = Signal()
- self.vga_vsync = vga_vsync = Signal()
- self.comb += pads.vsync.eq(vga_vsync)
- self.comb += pads.hsync.eq(vga_hsync)
- self.comb += pads.red.eq(pixel[16:21])
- self.comb += pads.green.eq(pixel[8:13])
- self.comb += pads.blue.eq(pixel[0:5])
- # CPU interface
- self.vsync = vsync = Signal()
- # framebuffer memory IO
- self.read_address = read_address = Signal(32)
- self.q = q = Signal(24)
- self.framebuffer_start = framebuffer_start = Signal(32)
- H_SYNC_PULSE = 96
- H_BACK_PORCH = 48 + H_SYNC_PULSE
- H_DATA = WIDTH + H_BACK_PORCH
- H_FRONT_PORCH = 16 + H_DATA
- V_SYNC_PULSE = 2
- V_BACK_PORCH = 29 + V_SYNC_PULSE
- V_DATA = HEIGHT + V_BACK_PORCH
- V_FRONT_PORCH = 10 + V_DATA
- pixel_counter = Signal(10)
- line_counter = Signal(10)
- framebuffer_current_address = Signal(ADDRESS_WIDTH)
- self.sync.clk += [
- q.eq(q+1),
- # default values
- pixel.eq(0),
- # horizontal timing for one line
- pixel_counter.eq(pixel_counter + 1),
- If (pixel_counter < H_SYNC_PULSE,
- vga_hsync.eq(0)
- ).Elif (pixel_counter < H_BACK_PORCH,
- vga_hsync.eq(1)
- ).Elif (pixel_counter == H_FRONT_PORCH,
- pixel_counter.eq(0),
- line_counter.eq(line_counter + 1)
- ),
- # vertical timing for one screen
- If (line_counter < V_SYNC_PULSE,
- vga_vsync.eq(0),
- vsync.eq(1)
- ).Elif (line_counter < V_BACK_PORCH,
- vga_vsync.eq(1),
- vsync.eq(0)
- ).Elif (line_counter == V_FRONT_PORCH,
- line_counter.eq(0),
- # latch framebuffer start on VSync
- framebuffer_current_address.eq(framebuffer_start),
- q.eq(0),
- ),
- # show pixels
- If ((line_counter >= V_BACK_PORCH) & (line_counter < V_DATA),
- If ((pixel_counter >= H_BACK_PORCH) & (pixel_counter < H_DATA),
- pixel.eq(q),
- framebuffer_current_address.eq(framebuffer_current_address + 1)
- )
- )
- ]
- class ClassicLed(Module):
- def __init__(self, pads):
- gpio.GPIOOut.__init__(self, pads)
- # CRG ----------------------------------------------------------------------------------------------
- class _CRG(Module):
- def __init__(self, platform):
- self.clock_domains.cd_sys = ClockDomain()
- self.clock_domains.cd_sys_ps = ClockDomain()
- self.clock_domains.cd_vga = ClockDomain()
- self.clock_domains.cd_por = ClockDomain(reset_less=True)
- # # #
- self.cd_sys.clk.attr.add("keep")
- self.cd_sys_ps.clk.attr.add("keep")
- self.cd_por.clk.attr.add("keep")
- # clock input always available
- clk12 = platform.request("clk12")
- # power on rst
- rst_n = Signal()
- self.sync.por += rst_n.eq(1)
- self.comb += [
- self.cd_por.clk.eq(clk12),
- self.cd_sys.rst.eq(~rst_n),
- self.cd_sys_ps.rst.eq(~rst_n)
- ]
- clk_outs = Signal(5)
- self.comb += self.cd_sys.clk.eq(clk_outs[0]) # C0
- self.comb += self.cd_sys_ps.clk.eq(clk_outs[1]) # C1
- # 25 MHz for 640x480. VESA standard is 25.175 MHz, but allows 0.5% deviation, close enough.
- self.comb += self.cd_vga.clk.eq(clk_outs[2]) # C2
- #
- # PLL we need 2 clocks one system one for SDRAM phase shifter
- #
- self.specials += \
- Instance("ALTPLL",
- p_BANDWIDTH_TYPE="AUTO",
- p_CLK0_DIVIDE_BY=6,
- p_CLK0_DUTY_CYCLE=50,
- p_CLK0_MULTIPLY_BY=25,
- p_CLK0_PHASE_SHIFT="0",
- p_CLK1_DIVIDE_BY=6,
- p_CLK1_DUTY_CYCLE=50,
- p_CLK1_MULTIPLY_BY=25,
- p_CLK1_PHASE_SHIFT="-10000",
- p_CLK2_DIVIDE_BY=12,
- p_CLK2_DUTY_CYCLE=50,
- p_CLK2_MULTIPLY_BY=25,
- p_CLK2_PHASE_SHIFT="0",
- p_COMPENSATE_CLOCK="CLK0",
- p_INCLK0_INPUT_FREQUENCY=83000,
- p_INTENDED_DEVICE_FAMILY="MAX 10",
- p_LPM_TYPE = "altpll",
- p_OPERATION_MODE = "NORMAL",
- i_INCLK=clk12,
- o_CLK=clk_outs, # we have total max 5 Cx clocks
- i_ARESET=~rst_n,
- i_CLKENA=0x3f,
- i_EXTCLKENA=0xf,
- i_FBIN=1,
- i_PFDENA=1,
- i_PLLENA=1,
- )
- self.comb += platform.request("sdram_clock").eq(self.cd_sys_ps.clk)
- # BaseSoC ------------------------------------------------------------------------------------------
- class BaseSoC(SoCSDRAM):
- #class BaseSoC(SoCCore):
- csr_peripherals = (
- "leds",
- )
- # csr_map.update(SoCCore.csr_map, csr_peripherals)
- def __init__(self, device, sys_clk_freq=int(50e6), **kwargs):
- assert sys_clk_freq == int(50e6)
- platform = max1000.Platform(device)
- # SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq,
- # integrated_rom_size=0x8000,
- # **kwargs)
- # csr_map_update(SoCSDRAM.csr_map, csr_peripherals)
- SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq,
- integrated_rom_size=0x6000,
- # integrated_main_ram_size=0x4000,
- **kwargs)
- self.mem_map['spiflash'] = 0x20000000
- spiflash_pads = platform.request('spiflash')
- self.add_memory_region(
- "spiflash", self.mem_map["spiflash"], 8*1024*1024)
- self.submodules.spiflash = SpiFlash(
- spiflash_pads,
- dummy=8,
- div=4,
- endianness=self.cpu.endianness)
- self.add_csr("spiflash")
- #self.spiflash.add_clk_primitive("xc7");
- # 8 MB flash: W74M64FVSSIQ
- self.add_constant("SPIFLASH_PAGE_SIZE", 256)
- self.add_constant("SPIFLASH_SECTOR_SIZE", 4096)
- self.add_constant("FLASH_BOOT_ADDRESS", self.mem_map['spiflash'])
- # spi_flash.py supports max 16MB linear space
- self.add_wb_slave(mem_decoder(self.mem_map["spiflash"]), self.spiflash.bus)
- self.submodules.crg = crg = _CRG(platform)
- self.submodules.vga = VgaOutputGenerator(platform.request('vga', 0), crg.cd_vga.clk)
- # self.submodules.leds = ClassicLed(Cat(platform.request("user_led", i) for i in range(7)))
- self.add_csr("leds", allow_user_defined=True)
- self.submodules.leds = ClassicLed(platform.request("user_led", 0))
- # self.add_csr("gpio_leds", allow_user_defined=True)
- self.add_csr("gpio_leds", allow_user_defined=True)
- self.submodules.gpio_leds = gpio.GPIOOut(platform.request("gpio_leds"))
- # use micron device as winbond and ISSI not available
- if not self.integrated_main_ram_size:
- self.submodules.sdrphy = GENSDRPHY(platform.request("sdram"))
- sdram_module = MT48LC4M16(self.clk_freq, "1:1")
- self.register_sdram(self.sdrphy,
- sdram_module.geom_settings,
- sdram_module.timing_settings)
- # Build --------------------------------------------------------------------------------------------
- def main():
- parser = argparse.ArgumentParser(description="LiteX SoC on MAX1000")
- builder_args(parser)
- parser.add_argument("device", choices=['8', '16'], help='Cyclone device: "8" for 10M08SAU169C8G or "16" for 10M16SAU169C8G')
- soc_sdram_args(parser)
- # soc_core_args(parser)
- args = parser.parse_args()
- if args.device == '16':
- device = '10M16SAU169C8G'
- else:
- device = '10M08SAU169C8G'
- soc = BaseSoC(device, **soc_sdram_argdict(args))
- # cls = BaseSoC
- # soc = cls(**soc_core_argdict(args))
- builder = Builder(soc, **builder_argdict(args))
- builder.build()
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement