Advertisement
Guest User

Untitled

a guest
Aug 9th, 2020
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.06 KB | None | 0 0
  1. import argparse
  2.  
  3. from nmigen import *
  4. from nmigen.build import Platform
  5. from nmigen_boards.ulx3s import *
  6.  
  7. from blink import Blink
  8. from vga2dvi import VGA2DVI
  9. from vga import VGA
  10. from ecp5pll import ECP5PLL
  11.  
  12.  
  13. #  modes tested on lenovo monitor
  14. #  640x400  @50Hz
  15. #  640x400  @60Hz
  16. #  640x480  @50Hz
  17. #  640x480  @60Hz
  18. #  720x576  @50Hz
  19. #  720x576  @60Hz
  20. #  800x480  @60Hz
  21. #  800x600  @60Hz
  22. # 1024x768  @60Hz
  23. # 1280x768  @60Hz
  24. # 1366x768  @60Hz
  25. # 1280x1024 @60Hz
  26. # 1920x1080 @30Hz
  27. # 1920x1080 @50Hz overclock 540MHz
  28. # 1920x1200 @50Hz overclock 600MHz
  29. class TopVGATest(Elaboratable):
  30.     def __init__(self,
  31.                  x=640, # pixels
  32.                  y=480, # pixels
  33.                  f=60, # Hz (60, 50, 30)
  34.                  xadjustf=0, # adjust -3..3 if no picture
  35.                  yadjustf=0, # or to fine-tune f
  36.                  ddr=True): # False: SDR, True: DDR
  37.         self.i_btn = Signal(7)
  38.         self.o_led = Signal(8)
  39.         self.o_gpdi_dp = Signal(4)
  40.         self.o_user_programn = Signal()
  41.         self.o_wifi_gpio0 = Signal()
  42.         # Configuration
  43.         self.x = x
  44.         self.y = y
  45.         self.f = f
  46.         self.xadjustf = xadjustf
  47.         self.yadjustf = yadjustf
  48.         self.ddr = ddr
  49.  
  50.     def find_next_f(self, f):
  51.         next_f = 0
  52.  
  53.         if (f < 25e6):
  54.             next_f = 25e6
  55.         elif (f > 27e6):
  56.             next_f = 27e6
  57.         elif (f > 40e6):
  58.             next_f = 40e6
  59.         elif (f > 50e6):
  60.             next_f = 50e6
  61.         elif (f > 54e6):
  62.             next_f = 54e6
  63.         elif (f > 60e6):
  64.             next_f = 60e6
  65.         elif (f > 65e6):
  66.             next_f = 65e6
  67.         elif (f > 75e6):
  68.             next_f = 75e6
  69.         elif (f > 80e6):
  70.             next_f = 80e6
  71.         elif (f > 100e6):
  72.             next_f = 100e6
  73.         elif (f > 108e6):
  74.             next_f = 108e6
  75.         elif (f > 120e6):
  76.             next_f = 120e6
  77.        
  78.         return next_f
  79.  
  80.     def elaborate(self, platform: Platform) -> Module:
  81.         m = Module()
  82.  
  83.         if platform:
  84.             clk_in = platform.request(platform.default_clk, dir='-')[0]
  85.  
  86.             # Constants
  87.             xminblank   = self.x // 64 # Initial estimate
  88.             yminblank   = self.y // 64 # for minimal blank space
  89.             min_pixel_f = self.f * (self.x + xminblank) * (self.y * yminblank)
  90.             pixel_f     = self.find_next_f(min_pixel_f)
  91.             yframe      = self.y + yminblank
  92.             xframe      = pixel_f // (self.f * yframe)
  93.             xblank      = xframe - self.x
  94.             yblank      = yframe - self.y
  95.             hsync_front_porch = xblank // 3
  96.             hsync_pulse_width = xblank // 3
  97.             hsync_back_porch  = xblank - hsync_pulse_width - hsync_front_porch + self.xadjustf
  98.             vsync_front_porch = yblank // 3
  99.             vsync_pulse_width = yblank // 3
  100.             vsync_back_porch  = yblank - vsync_pulse_width - vsync_front_porch + self.yadjustf
  101.  
  102.             # o_wifi_gpio0 = 1 keeps board from rebooting
  103.             # Hold btn0 to let ESP32 take control of the board.
  104.             m.d.comb += self.o_wifi_gpio0.eq(self.i_btn[0])
  105.  
  106.             # Press btn0 to exit this bitstream.
  107.             R_delay_reload = Signal(20, reset=0)
  108.             with m.If(R_delay_reload[19] == 0):
  109.                 m.d.sync += R_delay_reload.eq(R_delay_reload + 1)
  110.             m.d.comb += self.o_user_programn.eq(self.i_btn[0] | ~R_delay_reload[19])
  111.  
  112.             # Clock generator.
  113.             m.domains.sync  = cd_sync  = ClockDomain("sync")
  114.             m.domains.pixel = cd_pixel = ClockDomain("pixel")
  115.             m.domains.shift = cd_shift = ClockDomain("shift")
  116.  
  117.             m.submodules.ecp5pll = pll = ECP5PLL()
  118.             pll.register_clkin(clk_in,  platform.default_clk_frequency)
  119.             pll.create_clkout(cd_sync,  platform.default_clk_frequency)
  120.             pll.create_clkout(cd_shift, pixel_f)
  121.             pll.create_clkout(cd_pixel, pixel_f * 5.0 * (1.0 if self.ddr else 2.0))
  122.  
  123.             # VGA signal generator.
  124.             vga_r = Signal(8)
  125.             vga_g = Signal(8)
  126.             vga_b = Signal(8)
  127.             vga_hsync = Signal()
  128.             vga_vsync = Signal()
  129.             vga_blank = Signal()
  130.  
  131.             m.submodules.vga = vga = VGA(
  132.                 resolution_x      = self.x,
  133.                 hsync_front_porch = hsync_front_porch,
  134.                 hsync_pulse       = hsync_pulse_width,
  135.                 hsync_back_porch  = hsync_back_porch,
  136.                 resolution_y      = self.y,
  137.                 vsync_front_porch = vsync_front_porch,
  138.                 vsync_pulse       = vsync_pulse_width,
  139.                 vsync_back_porch  = vsync_back_porch,
  140.                 bits_x            = 11,
  141.                 bits_y            = 11
  142.             )
  143.             m.d.comb += [
  144.                 vga.i_clk_en.eq(1),
  145.                 vga.i_test_picture.eq(1),
  146.                 vga.i_r.eq(0),
  147.                 vga.i_g.eq(0),
  148.                 vga.i_b.eq(0),
  149.                 vga_r.eq(vga.o_vga_r),
  150.                 vga_g.eq(vga.o_vga_g),
  151.                 vga_b.eq(vga.o_vga_b),
  152.                 vga_hsync.eq(vga.o_vga_hsync),
  153.                 vga_vsync.eq(vga.o_vga_vsync),
  154.                 vga_blank.eq(vga.o_vga_blank),
  155.             ]
  156.  
  157.             # VGA to digital video converter.
  158.             tmds = [Signal(2) for i in range(4)]
  159.             m.submodules.vga2dvid = vga2dvid = VGA2DVI()
  160.             m.d.comb += [
  161.                 vga2dvid.i_red.eq(vga_r),
  162.                 vga2dvid.i_green.eq(vga_g),
  163.                 vga2dvid.i_blue.eq(vga_b),
  164.                 vga2dvid.i_hsync.eq(vga_hsync),
  165.                 vga2dvid.i_vsync.eq(vga_vsync),
  166.                 vga2dvid.i_blank.eq(vga_blank),
  167.                 tmds[3].eq(vga2dvid.o_clk),
  168.                 tmds[2].eq(vga2dvid.o_red),
  169.                 tmds[1].eq(vga2dvid.o_green),
  170.                 tmds[0].eq(vga2dvid.o_blue),
  171.             ]
  172.  
  173.             # LED blinky
  174.             counter_width = 28
  175.             countblink = Signal(8)
  176.             m.submodules.blink = blink = Blink(counter_width)
  177.             m.d.comb += [
  178.                 countblink.eq(blink.o_led),
  179.                 self.o_led[6:8].eq(countblink[6:8]),
  180.                 self.o_led[0].eq(vga_vsync),
  181.                 self.o_led[1].eq(vga_hsync),
  182.                 self.o_led[2].eq(vga_blank),
  183.             ]
  184.  
  185.             # if (self.ddr):
  186.             #     # Vendor specific DDR modules.
  187.             #     # Convert SDR 2-bit input to DDR clocked 1-bit output (single-ended)
  188.             #     # onboard GPDI.
  189.                
  190.             #     m.submodules.ddr0_clock = ODDRX1F()
  191.             #     m.submodules.ddr0_red   = ODDRX1F()
  192.             #     m.submodules.ddr0_green = ODDRX1F()
  193.             #     m.submodules.ddr0_blue  = ODDRX1F()
  194.             # else:
  195.             m.d.comb += [
  196.                 self.o_gpdi_dp[3].eq(tmds[3][0]),
  197.                 self.o_gpdi_dp[2].eq(tmds[2][0]),
  198.                 self.o_gpdi_dp[1].eq(tmds[1][0]),
  199.                 self.o_gpdi_dp[0].eq(tmds[0][0]),
  200.             ]
  201.  
  202.         return m
  203.  
  204.  
  205. if __name__ == "__main__":
  206.     variants = {
  207.         '12F': ULX3S_12F_Platform,
  208.         '25F': ULX3S_25F_Platform,
  209.         '45F': ULX3S_45F_Platform,
  210.         '85F': ULX3S_85F_Platform
  211.     }
  212.  
  213.     # Figure out which FPGA variant we want to target...
  214.     parser = argparse.ArgumentParser()
  215.     parser.add_argument('variant', choices=variants.keys())
  216.     args = parser.parse_args()
  217.    
  218.     #platform = variants[args.variant]
  219.     platform = ULX3S_85F_Platform
  220.  
  221.     m = Module()
  222.     m.submodules.top = top = TopVGATest(ddr=False)
  223.  
  224.     #leds = platform.request("led", 0)
  225.     #btns = platform.request("button", 0)
  226.  
  227.     btns = [platform.request("button_pwr"),
  228.             platform.request("button_fire", 0),
  229.             platform.request("button_fire", 1),
  230.             platform.request("button_up"),
  231.             platform.request("button_down"),
  232.             platform.request("button_left"),
  233.             platform.request("button_right")]
  234.  
  235.     for i in range(len(btns)):
  236.             m.d.comb += top.i_btn[i].eq(btns[i])
  237.  
  238.     platform().build(m, do_program=False)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement