Advertisement
Guest User

Untitled

a guest
Nov 8th, 2019
321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.22 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. # This file is Copyright (c) 2019 Antti Lukats <[email protected]>
  4. # This file is Copyright (c) 2019 msloniewski <[email protected]>
  5. # License: BSD
  6.  
  7. import argparse
  8.  
  9. from migen import *
  10.  
  11. from litex_boards.partner.platforms import max1000
  12.  
  13. from litex.soc.integration.soc_core import *
  14. from litex.soc.integration.soc_sdram import *
  15.  
  16. from litex.soc.integration.builder import *
  17.  
  18. from litedram.modules import MT48LC4M16
  19. from litedram.phy import GENSDRPHY
  20.  
  21. from litex.soc.cores import gpio
  22. from litex.soc.cores.spi_flash import SpiFlash
  23.  
  24. class VgaOutputGenerator(Module):
  25.     def __init__(self, pads, clk):
  26.         self.clock_domains.cd_clk = ClockDomain()
  27.         self.comb += self.cd_clk.clk.eq(clk)
  28.        
  29.         WIDTH = 640
  30.         HEIGHT = 480
  31.         BIT_DEPTH = 8
  32.         ADDRESS_WIDTH = 32
  33.  
  34.         # VGA output
  35.         self.pixel = pixel = Signal(24)
  36.         self.vga_hsync = vga_hsync = Signal()
  37.         self.vga_vsync = vga_vsync = Signal()
  38.  
  39.         self.comb += pads.vsync.eq(vga_vsync)
  40.         self.comb += pads.hsync.eq(vga_hsync)
  41.         self.comb += pads.red.eq(pixel[16:21])
  42.         self.comb += pads.green.eq(pixel[8:13])
  43.         self.comb += pads.blue.eq(pixel[0:5])
  44.        
  45.         # CPU interface
  46.         self.vsync = vsync = Signal()
  47.        
  48.         # framebuffer memory IO
  49.         self.read_address = read_address = Signal(32)
  50.         self.q = q = Signal(24)
  51.         self.framebuffer_start = framebuffer_start = Signal(32)
  52.  
  53.         H_SYNC_PULSE = 96
  54.         H_BACK_PORCH = 48 + H_SYNC_PULSE
  55.         H_DATA = WIDTH + H_BACK_PORCH
  56.         H_FRONT_PORCH = 16 + H_DATA
  57.  
  58.         V_SYNC_PULSE = 2
  59.         V_BACK_PORCH = 29 + V_SYNC_PULSE
  60.         V_DATA = HEIGHT + V_BACK_PORCH
  61.         V_FRONT_PORCH = 10 + V_DATA
  62.  
  63.         pixel_counter = Signal(10)
  64.         line_counter = Signal(10)
  65.  
  66.         framebuffer_current_address = Signal(ADDRESS_WIDTH)
  67.        
  68.         self.sync.clk += [
  69.             q.eq(q+1),
  70.             # default values
  71.             pixel.eq(0),
  72.            
  73.             # horizontal timing for one line
  74.             pixel_counter.eq(pixel_counter + 1),
  75.             If (pixel_counter < H_SYNC_PULSE,
  76.                 vga_hsync.eq(0)
  77.             ).Elif (pixel_counter < H_BACK_PORCH,
  78.                 vga_hsync.eq(1)
  79.             ).Elif (pixel_counter == H_FRONT_PORCH,
  80.                 pixel_counter.eq(0),
  81.                 line_counter.eq(line_counter + 1)
  82.             ),
  83.  
  84.             # vertical timing for one screen
  85.             If (line_counter < V_SYNC_PULSE,
  86.                 vga_vsync.eq(0),
  87.                 vsync.eq(1)
  88.             ).Elif (line_counter < V_BACK_PORCH,
  89.                 vga_vsync.eq(1),
  90.                 vsync.eq(0)
  91.             ).Elif (line_counter == V_FRONT_PORCH,
  92.                 line_counter.eq(0),
  93.  
  94.                 # latch framebuffer start on VSync
  95.                 framebuffer_current_address.eq(framebuffer_start),
  96.                 q.eq(0),
  97.             ),
  98.            
  99.             # show pixels
  100.             If ((line_counter >= V_BACK_PORCH) & (line_counter < V_DATA),
  101.                 If ((pixel_counter >= H_BACK_PORCH) & (pixel_counter < H_DATA),
  102.                     pixel.eq(q),
  103.                     framebuffer_current_address.eq(framebuffer_current_address + 1)
  104.                 )
  105.             )
  106.         ]
  107.        
  108.        
  109.  
  110. class ClassicLed(Module):
  111.     def __init__(self, pads):
  112.         gpio.GPIOOut.__init__(self, pads)
  113.  
  114. # CRG ----------------------------------------------------------------------------------------------
  115. class _CRG(Module):
  116.     def __init__(self, platform):
  117.         self.clock_domains.cd_sys = ClockDomain()
  118.         self.clock_domains.cd_sys_ps = ClockDomain()
  119.         self.clock_domains.cd_vga = ClockDomain()
  120.         self.clock_domains.cd_por = ClockDomain(reset_less=True)
  121.  
  122.         # # #
  123.  
  124.         self.cd_sys.clk.attr.add("keep")
  125.         self.cd_sys_ps.clk.attr.add("keep")
  126.         self.cd_por.clk.attr.add("keep")
  127.  
  128.         # clock input always available
  129.         clk12 = platform.request("clk12")
  130.  
  131.         # power on rst
  132.         rst_n = Signal()
  133.         self.sync.por += rst_n.eq(1)
  134.         self.comb += [
  135.             self.cd_por.clk.eq(clk12),
  136.             self.cd_sys.rst.eq(~rst_n),
  137.             self.cd_sys_ps.rst.eq(~rst_n)
  138.         ]
  139.  
  140.         clk_outs = Signal(5)
  141.  
  142.         self.comb += self.cd_sys.clk.eq(clk_outs[0]) # C0
  143.         self.comb += self.cd_sys_ps.clk.eq(clk_outs[1]) # C1
  144.        
  145.         # 25 MHz for 640x480. VESA standard is 25.175 MHz, but allows 0.5% deviation, close enough.
  146.         self.comb += self.cd_vga.clk.eq(clk_outs[2]) # C2
  147.  
  148.         #
  149.         # PLL we need 2 clocks one system one for SDRAM phase shifter
  150.         #
  151.  
  152.         self.specials += \
  153.             Instance("ALTPLL",
  154.                 p_BANDWIDTH_TYPE="AUTO",
  155.                 p_CLK0_DIVIDE_BY=6,
  156.                 p_CLK0_DUTY_CYCLE=50,
  157.                 p_CLK0_MULTIPLY_BY=25,
  158.                 p_CLK0_PHASE_SHIFT="0",
  159.                 p_CLK1_DIVIDE_BY=6,
  160.                 p_CLK1_DUTY_CYCLE=50,
  161.                 p_CLK1_MULTIPLY_BY=25,
  162.                 p_CLK1_PHASE_SHIFT="-10000",
  163.                 p_CLK2_DIVIDE_BY=12,
  164.                 p_CLK2_DUTY_CYCLE=50,
  165.                 p_CLK2_MULTIPLY_BY=25,
  166.                 p_CLK2_PHASE_SHIFT="0",
  167.                 p_COMPENSATE_CLOCK="CLK0",
  168.                 p_INCLK0_INPUT_FREQUENCY=83000,
  169.                 p_INTENDED_DEVICE_FAMILY="MAX 10",
  170.                 p_LPM_TYPE = "altpll",
  171.                 p_OPERATION_MODE = "NORMAL",
  172.                 i_INCLK=clk12,
  173.                 o_CLK=clk_outs, # we have total max 5 Cx clocks
  174.                 i_ARESET=~rst_n,
  175.                 i_CLKENA=0x3f,
  176.                 i_EXTCLKENA=0xf,
  177.                 i_FBIN=1,
  178.                 i_PFDENA=1,
  179.                 i_PLLENA=1,
  180.             )
  181.         self.comb += platform.request("sdram_clock").eq(self.cd_sys_ps.clk)
  182.  
  183. # BaseSoC ------------------------------------------------------------------------------------------
  184.  
  185. class BaseSoC(SoCSDRAM):
  186. #class BaseSoC(SoCCore):
  187.     csr_peripherals = (
  188.         "leds",
  189.     )
  190. #    csr_map.update(SoCCore.csr_map, csr_peripherals)
  191.  
  192.     def __init__(self, device, sys_clk_freq=int(50e6), **kwargs):
  193.         assert sys_clk_freq == int(50e6)
  194.  
  195.         platform = max1000.Platform(device)
  196.  
  197. #        SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq,
  198. #                          integrated_rom_size=0x8000,
  199. #                          **kwargs)
  200.  
  201.  
  202. #    csr_map_update(SoCSDRAM.csr_map, csr_peripherals)
  203.  
  204.         SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq,
  205.             integrated_rom_size=0x6000,
  206. #            integrated_main_ram_size=0x4000,
  207.             **kwargs)
  208.  
  209.         self.mem_map['spiflash'] = 0x20000000
  210.         spiflash_pads = platform.request('spiflash')
  211.         self.add_memory_region(
  212.             "spiflash", self.mem_map["spiflash"], 8*1024*1024)
  213.  
  214.         self.submodules.spiflash = SpiFlash(
  215.                 spiflash_pads,
  216.                 dummy=8,
  217.                 div=4,
  218.                 endianness=self.cpu.endianness)
  219.         self.add_csr("spiflash")
  220.  
  221.         #self.spiflash.add_clk_primitive("xc7");    
  222.  
  223.         # 8 MB flash: W74M64FVSSIQ
  224.         self.add_constant("SPIFLASH_PAGE_SIZE", 256)
  225.         self.add_constant("SPIFLASH_SECTOR_SIZE", 4096)
  226.         self.add_constant("FLASH_BOOT_ADDRESS", self.mem_map['spiflash'])
  227.  
  228.         # spi_flash.py supports max 16MB linear space
  229.         self.add_wb_slave(mem_decoder(self.mem_map["spiflash"]), self.spiflash.bus)
  230.  
  231.  
  232.         self.submodules.crg = crg = _CRG(platform)
  233.  
  234.         self.submodules.vga = VgaOutputGenerator(platform.request('vga', 0), crg.cd_vga.clk)
  235.  
  236. #        self.submodules.leds = ClassicLed(Cat(platform.request("user_led", i) for i in range(7)))
  237.         self.add_csr("leds", allow_user_defined=True)
  238.         self.submodules.leds = ClassicLed(platform.request("user_led", 0))
  239.  
  240. #        self.add_csr("gpio_leds", allow_user_defined=True)
  241.         self.add_csr("gpio_leds", allow_user_defined=True)
  242.         self.submodules.gpio_leds = gpio.GPIOOut(platform.request("gpio_leds"))
  243.  
  244.  
  245. # use micron device as winbond and ISSI not available
  246.  
  247.         if not self.integrated_main_ram_size:
  248.             self.submodules.sdrphy = GENSDRPHY(platform.request("sdram"))
  249.             sdram_module = MT48LC4M16(self.clk_freq, "1:1")
  250.             self.register_sdram(self.sdrphy,
  251.                                 sdram_module.geom_settings,
  252.                                 sdram_module.timing_settings)
  253.  
  254. # Build --------------------------------------------------------------------------------------------
  255.  
  256. def main():
  257.     parser = argparse.ArgumentParser(description="LiteX SoC on MAX1000")
  258.     builder_args(parser)
  259.     parser.add_argument("device", choices=['8', '16'], help='Cyclone device: "8" for 10M08SAU169C8G or "16" for 10M16SAU169C8G')
  260.  
  261.     soc_sdram_args(parser)
  262. #    soc_core_args(parser)
  263.  
  264.     args = parser.parse_args()
  265.  
  266.     if args.device == '16':
  267.         device = '10M16SAU169C8G'
  268.     else:
  269.         device = '10M08SAU169C8G'
  270.     soc = BaseSoC(device, **soc_sdram_argdict(args))
  271.  
  272. #    cls = BaseSoC
  273. #    soc = cls(**soc_core_argdict(args))
  274.  
  275.     builder = Builder(soc, **builder_argdict(args))
  276.     builder.build()
  277.  
  278.  
  279. if __name__ == "__main__":
  280.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement