From 25775594d98e89673f7764292d14644834918488 Mon Sep 17 00:00:00 2001 From: YRabbit Date: Sun, 3 Dec 2023 19:02:57 +1000 Subject: [PATCH] Himbaechel. Add initial BSRAM support (#202) * Himbaechel. Add initial BSRAM support - added support for data generation for BSRAM initialization in a bit image; - BSRAM Bels are created; - pROM/pROMX9 primitives with widths of 1, 2, 4, 8, 9, 16, 18 bits are supported. - start of unpacking - only attributes. Signed-off-by: YRabbit * Himbaechel. Add BSRAM for all chips. The following primitives are implemented for the GW1N-1, GW2A-18, GW2AR-18C, GW1NSR-4C, GW1NR-9C, GW1NR-9 and GW1N-4 chips: * pROM - read only memory - (bitwidth: 1, 2, 4, 8, 16, 32). * pROMX9 - read only memory - (bitwidth: 9, 18, 36). * SDPB - semidual port - (bitwidth: 1, 2, 4, 8, 16, 32). * SDPX9B - semidual port - (bitwidth: 9, 18, 36). * DPB - dual port - (bitwidth: 16). * DPX9B - dual port - (bitwidth: 18). * SP - single port - (bitwidth: 1, 2, 4, 8, 16, 32). * SPX9 - single port - (bitwidth: 9, 18, 36). For GW1NSR-4C and GW1NR-9 chips, SP/SPX9 primitives with data widths of 32/36 bits are implemented using a pair of 16-bit wide primitives. Added examples for all boards except those based on GW1NSR-4C, GW1NR-9 and GW1N-4 chips for memory primitives with a width of 8 bits (as well as 16 bits where 8 is not supported). And these very examples are the weakest point - I tried to make the primitives themselves work and the result of compiling the examples was similar between the vendor IDE and Apicula, but the examples themselves were poorly written. This is due to my lack of experience working with BSRAM. In general, they need to be rewritten. Signed-off-by: YRabbit * Fix symbolic links. Signed-off-by: YRabbit * Fix another symbolic link. Signed-off-by: YRabbit --------- Signed-off-by: YRabbit --- apycula/attrids.py | 8 +- apycula/bslib.py | 7 + apycula/chipdb.py | 134 ++++++++++++++- apycula/gowin_pack.py | 218 +++++++++++++++++++++++- apycula/gowin_unpack.py | 36 +++- examples/himbaechel/DPB-image-rom.v | 1 + examples/himbaechel/DPB-video-ram.v | 51 ++++++ examples/himbaechel/DPB.v | 175 +++++++++++++++++++ examples/himbaechel/DPB16-image-rom.v | 44 +++++ examples/himbaechel/DPB16-video-ram.v | 51 ++++++ examples/himbaechel/DPB16.v | 177 +++++++++++++++++++ examples/himbaechel/DPX9B-image-rom.v | 1 + examples/himbaechel/DPX9B-video-ram.v | 51 ++++++ examples/himbaechel/DPX9B.v | 175 +++++++++++++++++++ examples/himbaechel/DPX9B18-image-rom.v | 44 +++++ examples/himbaechel/DPX9B18-video-ram.v | 51 ++++++ examples/himbaechel/DPX9B18.v | 176 +++++++++++++++++++ examples/himbaechel/Makefile.himbaechel | 63 ++++++- examples/himbaechel/SDPB-image-rom.v | 1 + examples/himbaechel/SDPB-video-ram.v | 43 +++++ examples/himbaechel/SDPB.v | 174 +++++++++++++++++++ examples/himbaechel/SDPX9B-image-rom.v | 1 + examples/himbaechel/SDPX9B-video-ram.v | 43 +++++ examples/himbaechel/SDPX9B.v | 174 +++++++++++++++++++ examples/himbaechel/SP-image-rom.v | 1 + examples/himbaechel/SP-video-ram.v | 35 ++++ examples/himbaechel/SP.v | 182 ++++++++++++++++++++ examples/himbaechel/SPX9-image-rom.v | 1 + examples/himbaechel/SPX9-video-ram.v | 35 ++++ examples/himbaechel/SPX9.v | 177 +++++++++++++++++++ examples/himbaechel/img-rom.vh | 67 ++++++++ examples/himbaechel/img-rom1.vh | 67 ++++++++ examples/himbaechel/img-rom2.vh | 67 ++++++++ examples/himbaechel/img-rom3.vh | 67 ++++++++ examples/himbaechel/img-video-ram.vh | 67 ++++++++ examples/himbaechel/img-video-ram1.vh | 67 ++++++++ examples/himbaechel/pROM-image-rom.v | 44 +++++ examples/himbaechel/pROM-video-ram.v | 2 + examples/himbaechel/pROM.v | 146 ++++++++++++++++ examples/himbaechel/pROMX9-image-rom.v | 44 +++++ examples/himbaechel/pROMX9-video-ram.v | 1 + examples/himbaechel/pROMX9.v | 146 ++++++++++++++++ examples/himbaechel/szfpga.cst | 25 +++ examples/himbaechel/tangnano1k.cst | 4 +- 44 files changed, 3121 insertions(+), 23 deletions(-) create mode 120000 examples/himbaechel/DPB-image-rom.v create mode 100644 examples/himbaechel/DPB-video-ram.v create mode 100644 examples/himbaechel/DPB.v create mode 100644 examples/himbaechel/DPB16-image-rom.v create mode 100644 examples/himbaechel/DPB16-video-ram.v create mode 100644 examples/himbaechel/DPB16.v create mode 120000 examples/himbaechel/DPX9B-image-rom.v create mode 100644 examples/himbaechel/DPX9B-video-ram.v create mode 100644 examples/himbaechel/DPX9B.v create mode 100644 examples/himbaechel/DPX9B18-image-rom.v create mode 100644 examples/himbaechel/DPX9B18-video-ram.v create mode 100644 examples/himbaechel/DPX9B18.v create mode 120000 examples/himbaechel/SDPB-image-rom.v create mode 100644 examples/himbaechel/SDPB-video-ram.v create mode 100644 examples/himbaechel/SDPB.v create mode 120000 examples/himbaechel/SDPX9B-image-rom.v create mode 100644 examples/himbaechel/SDPX9B-video-ram.v create mode 100644 examples/himbaechel/SDPX9B.v create mode 120000 examples/himbaechel/SP-image-rom.v create mode 100644 examples/himbaechel/SP-video-ram.v create mode 100644 examples/himbaechel/SP.v create mode 120000 examples/himbaechel/SPX9-image-rom.v create mode 100644 examples/himbaechel/SPX9-video-ram.v create mode 100644 examples/himbaechel/SPX9.v create mode 100644 examples/himbaechel/img-rom.vh create mode 100644 examples/himbaechel/img-rom1.vh create mode 100644 examples/himbaechel/img-rom2.vh create mode 100644 examples/himbaechel/img-rom3.vh create mode 100644 examples/himbaechel/img-video-ram.vh create mode 100644 examples/himbaechel/img-video-ram1.vh create mode 100644 examples/himbaechel/pROM-image-rom.v create mode 100644 examples/himbaechel/pROM-video-ram.v create mode 100644 examples/himbaechel/pROM.v create mode 100644 examples/himbaechel/pROMX9-image-rom.v create mode 120000 examples/himbaechel/pROMX9-video-ram.v create mode 100644 examples/himbaechel/pROMX9.v diff --git a/apycula/attrids.py b/apycula/attrids.py index 4c4071f4..8a7205d7 100644 --- a/apycula/attrids.py +++ b/apycula/attrids.py @@ -332,16 +332,16 @@ 'SPB_BEHB': 50, 'SPB_BELB': 51, 'SPA_MODE': 52, - 'SPA_REG_MODE': 53, + 'SPA_REGMODE': 53, 'SPB_MODE': 54, - 'SPB_REG_MODE': 55, + 'SPB_REGMODE': 55, 'ROMA_DATA_WIDTH': 56, 'ROMB_DATA_WIDTH': 57, 'ROM_DATA_WIDTH': 58, 'ROM_PORTA_BEHB': 59, 'ROM_PORTA_BELB': 60, - 'ROM_PORTA_REGMODE':61, - 'ROM_PORTB_REGMODE':62, + 'ROMA_REGMODE': 61, + 'ROMB_REGMODE': 62, 'PORTB_BELB': 63, 'PORTA_MODE': 64, 'PORTB_MODE': 65, diff --git a/apycula/bslib.py b/apycula/bslib.py index c9680bc7..062b8131 100644 --- a/apycula/bslib.py +++ b/apycula/bslib.py @@ -80,6 +80,13 @@ def compressLine(line, key8Z, key4Z, key2Z): newline += val.replace(2 * b'\x00', bytes([key2Z])) return newline +def write_bitstream_with_bsram_init(fname, bs, hdr, ftr, compress, bsram_init): + new_bs = np.vstack((bs, bsram_init)) + new_hdr = hdr.copy() + frames = int.from_bytes(new_hdr[-1][2:], 'big') + bsram_init.shape[0] + new_hdr[-1][2:] = frames.to_bytes(2, 'big') + write_bitstream(fname, new_bs, new_hdr, ftr, compress) + def write_bitstream(fname, bs, hdr, ftr, compress): bs = np.fliplr(bs) if compress: diff --git a/apycula/chipdb.py b/apycula/chipdb.py index f1aa3e84..504a14c7 100644 --- a/apycula/chipdb.py +++ b/apycula/chipdb.py @@ -7,7 +7,7 @@ from collections import namedtuple import numpy as np import apycula.fuse_h4x as fuse -from apycula.wirenames import wirenames, clknames, clknumbers, hclknames, hclknumbers +from apycula.wirenames import wirenames, wirenumbers, clknames, clknumbers, hclknames, hclknumbers from apycula import pindef # the character that marks the I/O attributes that come from the nextpnr @@ -447,6 +447,7 @@ def set_banks(fse, db): 13: 'BSRAM', 14: 'DSP', 15: 'PLL', + 39: 'BSRAM_INIT', 59: 'CFG', 62: 'OSC', 63: 'USB', @@ -464,6 +465,10 @@ def set_banks(fse, db): 26: 'CLS1', 27: 'CLS2', 28: 'CLS3', + 29: 'BSRAM_DP', + 30: 'BSRAM_SDP', + 31: 'BSRAM_SP', + 32: 'BSRAM_ROM', 35: 'PLL', 37: 'BANK', 40: 'IOBC', @@ -1191,7 +1196,7 @@ def fse_iologic(device, fse, ttyp): # the column indicated there is the last column of the left quadrant. # It is enough to empirically determine the correspondence of clocks and -# speakers in the new quadrant (even three clocks is enough, since the fourth +# columns in the new quadrant (even three clocks is enough, since the fourth # becomes obvious). # [3, 2, 1, 0] turned out to be the unwritten standard for all the chips studied. @@ -1228,9 +1233,9 @@ def fse_iologic(device, fse, ttyp): # wires of the same name involved in some kind of switching anywhere in the # chip are combined into one Himbaechel node. Further, when routing, there is # already a choice of which pip to use and which cell. -# It also follows that for the Himbaechel watch wires should not be mixed +# It also follows that for the Himbaechel clock wires should not be mixed # together with any other wires. At least I came to this conclusion and that -# is why the HCLK wires, which have the same numbers as the watch spines, are +# is why the HCLK wires, which have the same numbers as the clock spines, are # stored separately. # dat['CmuxIns'] and 80 - here, the places of entry points into the clock @@ -1386,7 +1391,7 @@ def fse_create_simplio_rows(dev, dat): dev.simplio_rows.add(row) def fse_create_tile_types(dev, dat): - type_chars = 'PCMI' + type_chars = 'PCMIB' for fn in type_chars: dev.tile_types[fn] = set() for row, rd in enumerate(dat['grid']): @@ -1404,6 +1409,25 @@ def fse_create_tile_types(dev, dat): j -= 1 dev.tile_types[fn].add(dev.grid[i][j].ttyp) +def get_tile_types_by_func(dev, dat, fse, fn): + ttypes = set() + fse_grid = fse['header']['grid'][61] + for row, rd in enumerate(dat['grid']): + for col, type_char in enumerate(rd): + if type_char == fn: + i = row + if i > 0: + i -= 1 + if i == len(fse_grid): + i -= 1 + j = col + if j > 0: + j -= 1 + if j == len(fse_grid[0]): + j -= 1 + ttypes.add(fse_grid[i][j]) + return ttypes + def fse_create_diff_types(dev, device): dev.diff_io_types = ['ELVDS_IBUF', 'ELVDS_OBUF', 'ELVDS_IOBUF', 'ELVDS_TBUF', 'TLVDS_IBUF', 'TLVDS_OBUF', 'TLVDS_IOBUF', 'TLVDS_TBUF'] @@ -1530,6 +1554,15 @@ def fse_create_gsr(dev, device): dev.extra_func.setdefault((row, col), {}).update( {'gsr': {'wire': 'C4'}}) +def fse_bram(fse, aux = False): + bels = {} + name = 'BSRAM' + if aux: + name = 'BSRAM_AUX' + bels[name] = Bel() + return bels + + def disable_plls(dev, device): if device in {'GW2A-18C'}: # (9, 0) and (9, 55) are the coordinates of cells when trying to place @@ -1547,6 +1580,8 @@ def from_fse(device, fse, dat): fse_create_simplio_rows(dev, dat) ttypes = {t for row in fse['header']['grid'][61] for t in row} tiles = {} + bram_ttypes = get_tile_types_by_func(dev, dat, fse, 'B') + bram_aux_ttypes = get_tile_types_by_func(dev, dat, fse, 'b') for ttyp in ttypes: w = fse[ttyp]['width'] h = fse[ttyp]['height'] @@ -1559,13 +1594,17 @@ def from_fse(device, fse, dat): tile.alonenode_6 = fse_alonenode(fse, ttyp, 6) if 5 in fse[ttyp]['shortval']: tile.bels = fse_luts(fse, ttyp) - if 51 in fse[ttyp]['shortval']: + elif 51 in fse[ttyp]['shortval']: tile.bels = fse_osc(device, fse, ttyp) + elif ttyp in bram_ttypes: + tile.bels = fse_bram(fse) + elif ttyp in bram_aux_ttypes: + tile.bels = fse_bram(fse, True) # These are the cell types in which PLLs can be located. To determine, # we first take the coordinates of the cells with the letters P and p # from the dat['grid'] table, and then, using these coordinates, # determine the type from fse['header']['grid'][61][row][col] - if ttyp in [42, 45, 74, 75, 76, 77, 78, 79, 86, 87, 88, 89]: + elif ttyp in [42, 45, 74, 75, 76, 77, 78, 79, 86, 87, 88, 89]: tile.bels = fse_pll(device, fse, ttyp) tile.bels.update(fse_iologic(device, fse, ttyp)) tiles[ttyp] = tile @@ -1775,6 +1814,7 @@ def json_pinout(device): _ides16_fixed_outputs = { 'Q0': 'F2', 'Q1': 'F3', 'Q2': 'F4', 'Q3': 'F5', 'Q4': 'Q0', 'Q5': 'Q1', 'Q6': 'Q2', 'Q7': 'Q3', 'Q8': 'Q4', 'Q9': 'Q5', 'Q10': 'F0', 'Q11': 'F1', 'Q12': 'F2', 'Q13': 'F3', 'Q14': 'F4', 'Q15': 'F5'} +_bsram_control_ins = ['CLK', 'OCE', 'CE', 'RESET', 'WRE'] def get_pllout_global_name(row, col, wire, device): for name, loc in _pll_loc[device].items(): if loc == (row, col, wire): @@ -1787,7 +1827,7 @@ def dat_portmap(dat, dev, device): for name, bel in tile.bels.items(): if bel.portmap: # GW2A has same PLL in different rows - if not (name.startswith("RPLLA") and device in {'GW2A-18', 'GW2A-18C'}): + if (not (name.startswith("RPLLA") and device in {'GW2A-18', 'GW2A-18C'})) and name != "BSRAM": continue if name.startswith("IOB"): if row in dev.simplio_rows: @@ -1845,6 +1885,84 @@ def dat_portmap(dat, dev, device): # dummy Input, we'll make a special pips for it bel.portmap[nam] = "FCLK" bel.portmap.update(_ides16_fixed_outputs) + elif name == 'BSRAM': + # dat['BsramOutDlt'] and dat['BsramOutDlt'] indicate port offset in cells + wire2node = {} # some wires used for >1 port, remember node + for i in range(len(dat['BsramOut'])): + off = dat['BsramOutDlt'][i] + wire_idx = dat['BsramOut'][i] + if wire_idx < 0: + continue + wire = wirenames[wire_idx] + # outs sequence: DO0-35, DOA0-17, DOB0-17 + if i < 36: + nam = f'DO{i}' + elif i < 54: + nam = f'DOA{i - 36}' + else: + nam = f'DOB{i - 36 - 18}' + # for aux cells create Himbaechel nodes + if off: + bel.portmap[nam] = f'BSRAM{nam}{wire}' + node = wire2node.get((row, col + off, wire), None) + if node: + dev.nodes[node][1].add((row, col, f'BSRAM{nam}{wire}')) + else: + dev.nodes.setdefault(f'X{col}Y{row}/BSRAM{nam}{wire}', ("BSRAM_O", {(row, col, f'BSRAM{nam}{wire}')}))[1].add((row, col + off, wire)) + wire2node[(row, col + off, wire)] = f'X{col}Y{row}/BSRAM{nam}{wire}' + else: + bel.portmap[nam] = wire + for i in range(len(dat['BsramIn']) + 6): + if i < 132: + off = dat['BsramInDlt'][i] + wire_idx = dat['BsramIn'][i] + if wire_idx < 0: + continue + elif i in range(132, 135): + nam = f'BLKSELA{i - 132}' + wire_idx = dat['BsramIn'][i - 132 + 15] + off = [0, 0, 2][i - 132] + else: + nam = f'BLKSELB{i - 135}' + wire_idx = wirenumbers[['CE2', 'LSR2', 'CE1'][i - 135]] + off = [1, 1, 2][i - 135] + wire = wirenames[wire_idx] + # helping the clock router + wire_type = 'BSRAM_I' + if wire.startswith('CLK') or wire.startswith('CE') or wire.startswith('LSR'): + wire_type = 'TILE_CLK' + # ins sequence: control(0-17), ADA0-13, AD0-13, DIA0-17, + # DI0-35, ADB0-13, DIB0-17, control(133-138) + # controls - A, B, '' like all controls for A (CLKA,), then for B (CLKB), + # then without modifier '' (CLK) + if i < 18: + if i < 15: + nam = _bsram_control_ins[i % 5] + ['A', 'B', ''][i // 5] + else: + nam = f'BLKSEL{i - 15}' + elif i < 32: + nam = f'ADA{i - 18}' + elif i < 46: + nam = f'AD{i - 32}' + elif i < 64: + nam = f'DIA{i - 46}' + elif i < 100: + nam = f'DI{i - 64}' + elif i < 114: + nam = f'ADB{i - 100}' + elif i < 132: + nam = f'DIB{i - 114}' + # for aux cells create Himbaechel nodes + if off: + bel.portmap[nam] = f'BSRAM{nam}{wire}' + node = wire2node.get((row, col + off, wire), None) + if node: + dev.nodes[node][1].add((row, col, f'BSRAM{nam}{wire}')) + else: + dev.nodes.setdefault(f'X{col}Y{row}/BSRAM{nam}{wire}', (wire_type, {(row, col, f'BSRAM{nam}{wire}')}))[1].add((row, col + off, wire)) + wire2node[(row, col + off, wire)] = f'X{col}Y{row}/BSRAM{nam}{wire}' + else: + bel.portmap[nam] = wire elif name == 'RPLLA': # The PllInDlt table seems to indicate in which cell the # inputs are actually located. diff --git a/apycula/gowin_pack.py b/apycula/gowin_pack.py index c3d3d859..3d8e5dac 100644 --- a/apycula/gowin_pack.py +++ b/apycula/gowin_pack.py @@ -21,6 +21,8 @@ device = "" pnr = None is_himbaechel = False +has_bsram_init = False +bsram_init_map = None # Sometimes it is convenient to know where a port is connected to enable # special fuses for VCC/VSS cases. @@ -79,10 +81,95 @@ def extra_pll_bels(cell, row, col, num, cellname): yield ('RPLLB', int(row), int(col) + offx * off, num, cell['parameters'], cell['attributes'], sanitize_name(cellname) + f'B{off}', cell) +def extra_bsram_bels(cell, row, col, num, cellname): + for off in [1, 2]: + yield ('BSRAM_AUX', int(row), int(col) + off, num, + cell['parameters'], cell['attributes'], sanitize_name(cellname) + f'AUX{off}', cell) + +# Explanation of what comes from and magic numbers. The process is this: you +# create a file with one primitive from the BSRAM family. In my case pROM. You +# give it a completely zero initialization. You generate an image. You specify +# one single unit bit at address 0 in the initialization. You generate an +# image. You compare. You sweep away garbage like CRC. +# Repeat 16 times. +# The 16th bit did not show much, but it allowed us to discover the meaning of +# the logicinfo table [39] - this is the location of a bit in the chip +# depending on its location in a 16-bit word. +# Next, we set the bits at address 2 (the next 16 bits) and compare. The result +# is unexpected: the bits no longer end up where we expect, but a certain pattern +# is present - bits 4 and 5 radically change the position of the bits in the +# chip, we take this into account. +# We repeat for bits up to the 13th --- since this is the maximum address in one SRAM block. +def store_bsram_init_val(db, row, col, typ, parms, attrs): + global bsram_init_map + global has_bsram_init + if typ == 'BSRAM_AUX' or 'INIT_RAM_00' not in parms: + return + + subtype = attrs['BSRAM_SUBTYPE'] + if not has_bsram_init: + has_bsram_init = True + # 256 * bsram rows * chip bit width + bsram_init_map = np.zeros((256 * len(db.simplio_rows), db.template.shape[1]), dtype=np.uint8) + # 3 BSRAM cells have width 3 * 60 + loc_map = np.zeros((256, 3 * 60), dtype = np.int8) + #print("mapping") + if not subtype.strip(): + width = 256 + elif subtype in {'X9'}: + width = 288 + else: + raise Exception(f"Init for {subtype} is not supported") + + def get_bits(init_data): + bit_no = 0 + ptr = -1 + while ptr >= -width: + if bit_no == 8 or bit_no == 17: + if width == 288: + yield (init_data[ptr], bit_no, lambda x: x) + ptr -= 1 + else: + yield ('0', bit_no, lambda x: x) + bit_no = (bit_no + 1) % 18 + else: + yield (init_data[ptr], bit_no, lambda x: x + 1) + ptr -= 1 + bit_no = (bit_no + 1) % 18 + + addr = -1 + for init_row in range(0x40): + init_data = parms[f'INIT_RAM_{init_row:02X}'] + #print(init_data) + for ptr_bit_inc in get_bits(init_data): + addr = ptr_bit_inc[2](addr) + if ptr_bit_inc[0] == '0': + continue + logic_line = ptr_bit_inc[1] * 4 + (addr >> 12) + bit = db.logicinfo['BSRAM_INIT'][logic_line][0] - 1 + quad = {0x30: 0xc0, 0x20: 0x40, 0x10: 0x80, 0x00: 0x0}[addr & 0x30] + map_row = quad + ((addr >> 6) & 0x3f) + #print(f'map_row:{map_row}, addr: {addr}, bit {ptr_bit_inc[1]}, bit:{bit}') + loc_map[map_row][bit] = 1 + + # now put one cell init data into global place + height = 256 + y = 0 + for brow in db.simplio_rows: + if row == brow: + break + y += height + x = 0 + for jdx in range(col): + x += db.grid[0][jdx].width + loc_map = np.flipud(loc_map) + bsram_init_map[y:y + height, x:x + 3 * 60] = loc_map + +_bsram_cell_types = {'DP', 'SDP', 'SP', 'ROM'} def get_bels(data): later = [] if is_himbaechel: - belre = re.compile(r"X(\d+)Y(\d+)/(?:GSR|LUT|DFF|IOB|MUX|ALU|ODDR|OSC[ZFHWO]?|BUF[GS]|RAM16SDP4|RAM16SDP2|RAM16SDP1|PLL|IOLOGIC)(\w*)") + belre = re.compile(r"X(\d+)Y(\d+)/(?:GSR|LUT|DFF|IOB|MUX|ALU|ODDR|OSC[ZFHWO]?|BUF[GS]|RAM16SDP4|RAM16SDP2|RAM16SDP1|PLL|IOLOGIC|BSRAM)(\w*)") else: belre = re.compile(r"R(\d+)C(\d+)_(?:GSR|SLICE|IOB|MUX2_LUT5|MUX2_LUT6|MUX2_LUT7|MUX2_LUT8|ODDR|OSC[ZFHWO]?|BUFS|RAMW|rPLL|PLLVR|IOLOGIC)(\w*)") @@ -113,6 +200,8 @@ def get_bels(data): if cell_type == 'rPLL': cell_type = 'RPLLA' yield from extra_pll_bels(cell, row, col, num, cellname) + if cell_type in _bsram_cell_types: + yield from extra_bsram_bels(cell, row, col, num, cellname) yield (cell_type, int(row), int(col), num, cell['parameters'], cell['attributes'], sanitize_name(cellname), cell) @@ -396,6 +485,113 @@ def set_pll_attrs(db, typ, idx, attrs): add_attr_val(db, 'PLL', fin_attrs, attrids.pll_attrids[attr], val) return fin_attrs +_bsram_bit_widths = { 1: '1', 2: '2', 4: '4', 8: '9', 9: '9', 16: '16', 18: '16', 32: 'X36', 36: 'X36'} +def set_bsram_attrs(db, typ, params): + bsram_attrs = {} + bsram_attrs['MODE'] = 'ENABLE' + bsram_attrs['GSR'] = 'DISABLE' + + for parm, val in params.items(): + if parm == 'BIT_WIDTH': + val = int(val, 2) + if val in _bsram_bit_widths: + if typ not in {'ROM'}: + if val in {16, 18}: # XXX no dynamic byte enable + bsram_attrs[f'{typ}A_BEHB'] = 'DISABLE' + bsram_attrs[f'{typ}A_BELB'] = 'DISABLE' + elif val in {32, 36}: # XXX no dynamic byte enable + bsram_attrs[f'{typ}A_BEHB'] = 'DISABLE' + bsram_attrs[f'{typ}A_BELB'] = 'DISABLE' + bsram_attrs[f'{typ}B_BEHB'] = 'DISABLE' + bsram_attrs[f'{typ}B_BELB'] = 'DISABLE' + if val not in {32, 36}: + bsram_attrs[f'{typ}A_DATA_WIDTH'] = _bsram_bit_widths[val] + bsram_attrs[f'{typ}B_DATA_WIDTH'] = _bsram_bit_widths[val] + elif typ != 'SP': + bsram_attrs['DBLWA'] = _bsram_bit_widths[val] + bsram_attrs['DBLWB'] = _bsram_bit_widths[val] + else: + raise Exception(f"BSRAM width of {val} isn't supported for now") + elif parm == 'BIT_WIDTH_0': + val = int(val, 2) + if val in _bsram_bit_widths: + if val not in {32, 36}: + bsram_attrs[f'{typ}A_DATA_WIDTH'] = _bsram_bit_widths[val] + else: + bsram_attrs['DBLWA'] = _bsram_bit_widths[val] + if val in {16, 18, 32, 36}: # XXX no dynamic byte enable + bsram_attrs[f'{typ}A_BEHB'] = 'DISABLE' + bsram_attrs[f'{typ}A_BELB'] = 'DISABLE' + else: + raise Exception(f"BSRAM width of {val} isn't supported for now") + elif parm == 'BIT_WIDTH_1': + val = int(val, 2) + if val in _bsram_bit_widths: + if val not in {32, 36}: + bsram_attrs[f'{typ}B_DATA_WIDTH'] = _bsram_bit_widths[val] + else: + bsram_attrs['DBLWB'] = _bsram_bit_widths[val] + if val in {16, 18, 32, 36}: # XXX no dynamic byte enable + bsram_attrs[f'{typ}B_BEHB'] = 'DISABLE' + bsram_attrs[f'{typ}B_BELB'] = 'DISABLE' + else: + raise Exception(f"BSRAM width of {val} isn't supported for now") + elif parm == 'BLK_SEL': + for i in range(3): + if val[-1 - i] == '0': + bsram_attrs[f'CSA_{i}'] = 'SET' + bsram_attrs[f'CSB_{i}'] = 'SET' + elif parm == 'BLK_SEL_0': + for i in range(3): + if val[-1 - i] == '0': + bsram_attrs[f'CSA_{i}'] = 'SET' + elif parm == 'BLK_SEL_1': + for i in range(3): + if val[-1 - i] == '0': + bsram_attrs[f'CSB_{i}'] = 'SET' + elif parm == 'READ_MODE0': + val = int(val, 2) + if val == 1: + bsram_attrs[f'{typ}A_REGMODE'] = 'OUTREG' + elif parm == 'READ_MODE1': + val = int(val, 2) + if val == 1: + bsram_attrs[f'{typ}B_REGMODE'] = 'OUTREG' + elif parm == 'READ_MODE': + val = int(val, 2) + if val == 1: + bsram_attrs[f'{typ}A_REGMODE'] = 'OUTREG' + bsram_attrs[f'{typ}B_REGMODE'] = 'OUTREG' + elif parm == 'RESET_MODE': + if val == 'ASYNC': + bsram_attrs[f'OUTREG_ASYNC'] = 'RESET' + elif parm == 'WRITE_MODE0': + val = int(val, 2) + if val == 1: + bsram_attrs[f'{typ}A_MODE'] = 'WT' + elif val == 2: + bsram_attrs[f'{typ}A_MODE'] = 'RBW' + elif parm == 'WRITE_MODE1': + val = int(val, 2) + if val == 1: + bsram_attrs[f'{typ}B_MODE'] = 'WT' + elif val == 2: + bsram_attrs[f'{typ}B_MODE'] = 'RBW' + elif parm == 'WRITE_MODE': + val = int(val, 2) + if val == 1: + bsram_attrs[f'{typ}A_MODE'] = 'WT' + bsram_attrs[f'{typ}B_MODE'] = 'WT' + elif val == 2: + bsram_attrs[f'{typ}A_MODE'] = 'RBW' + bsram_attrs[f'{typ}B_MODE'] = 'RBW' + fin_attrs = set() + for attr, val in bsram_attrs.items(): + if isinstance(val, str): + val = attrids.bsram_attrvals[val] + add_attr_val(db, 'BSRAM', fin_attrs, attrids.bsram_attrids[attr], val) + return fin_attrs + def set_osc_attrs(db, typ, params): osc_attrs = dict() for param, val in params.items(): @@ -585,7 +781,10 @@ def refine_io_attrs(attr): def place_lut(db, tiledata, tile, parms, num): lutmap = tiledata.bels[f'LUT{num}'].flags init = str(parms['INIT']) - init = init*(16//len(init)) + if len(init) > 16: + init = init[-16:] + else: + init = init*(16//len(init)) for bitnum, lutbit in enumerate(init[::-1]): if lutbit == '0': fuses = lutmap[bitnum] @@ -825,6 +1024,15 @@ def place(db, tilemap, bels, cst, args): bits = get_shortval_fuses(db, tiledata.ttyp, iologic_attrs, table_type) for r, c in bits: tile[r][c] = 1 + elif typ in _bsram_cell_types or typ == 'BSRAM_AUX': + store_bsram_init_val(db, row - 1, col -1, typ, parms, attrs) + if typ == 'BSRAM_AUX': + typ = cell['type'] + bsram_attrs = set_bsram_attrs(db, typ, parms) + bsrambits = get_shortval_fuses(db, tiledata.ttyp, bsram_attrs, f'BSRAM_{typ}') + print(f'({row - 1}, {col - 1}) attrs:{bsram_attrs}, bits:{bsrambits}') + for brow, bcol in bsrambits: + tile[brow][bcol] = 1 elif typ.startswith('RPLL'): pll_attrs = set_pll_attrs(db, 'RPLL', 0, parms) bits = set() @@ -1209,7 +1417,11 @@ def main(): header_footer(db, res, args.compress) if pil_available and args.png: bslib.display(args.png, res) - bslib.write_bitstream(args.output, res, db.cmd_hdr, db.cmd_ftr, args.compress) + + if has_bsram_init: + bslib.write_bitstream_with_bsram_init(args.output, res, db.cmd_hdr, db.cmd_ftr, args.compress, bsram_init_map) + else: + bslib.write_bitstream(args.output, res, db.cmd_hdr, db.cmd_ftr, args.compress) if args.cst: with open(args.cst, "w") as f: cst.write(f) diff --git a/apycula/gowin_unpack.py b/apycula/gowin_unpack.py index b8566f75..9099b3eb 100644 --- a/apycula/gowin_unpack.py +++ b/apycula/gowin_unpack.py @@ -293,6 +293,17 @@ def get_pll_A(db, row, col, typ): 'MIDDRX5': 'IDES10', 'IDDRX5': 'IDES10', 'IDDRX8': 'IDES16', } + +# BSRAM have 3 cells: BSRAM, BSRAM0 and BSRAM1 +# { (row, col) : idx } +_bsram_cells = {} +def get_bsram_main_cell(db, row, col, typ): + if typ[-4:] == '_AUX': + col -= 1 + if 'BSRAM_AUX' in db.grid[row][col].bels: + col -= 2 + return row, col + # noiostd --- this is the case when the function is called # with iostd by default, e.g. from the clock fuzzer # With normal gowin_unpack io standard is determined first and it is known. @@ -339,10 +350,21 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True) if modes: bels[name] = modes continue + if name.startswith("BSRAM"): + # disabled BSRAM cells have no fuse tables + if 'BSRAM_SP' not in db.shortval[tiledata.ttyp]: + continue + idx = _bsram_cells.setdefault(get_bsram_main_cell(db, row, col, name), len(_bsram_cells)) + #print(row, col, name, idx, tiledata.ttyp) + attrvals = parse_attrvals(tile, db.logicinfo['BSRAM'], db.shortval[tiledata.ttyp]['BSRAM_SP'], attrids.bsram_attrids) + if not attrvals: + continue + #print(row, col, name, idx, tiledata.ttyp, attrvals) + bels[f'{name}'] = {} + continue if name.startswith("IOLOGIC"): idx = name[-1] attrvals = parse_attrvals(tile, db.logicinfo['IOLOGIC'], db.shortval[tiledata.ttyp][f'IOLOGIC{idx}'], attrids.iologic_attrids) - #print(row, col, attrvals) if not attrvals: continue if 'OUTMODE' in attrvals.keys(): @@ -781,7 +803,7 @@ def tile2verilog(dbrow, dbcol, bels, pips, clock_pips, mod, cst, db): mod.wires.update({srcg, destg}) mod.assigns.append((destg, srcg)) - belre = re.compile(r"(IOB|LUT|DFF|BANK|CFG|ALU|RAM16|ODDR|OSC[ZFHWO]?|BUFS|RPLL[AB]|PLLVR|IOLOGIC)(\w*)") + belre = re.compile(r"(IOB|LUT|DFF|BANK|CFG|ALU|RAM16|ODDR|OSC[ZFHWO]?|BUFS|RPLL[AB]|PLLVR|IOLOGIC|BSRAM)(\w*)") bels_items = move_iologic(bels) iologic_detected = set() @@ -890,6 +912,15 @@ def tile2verilog(dbrow, dbcol, bels, pips, clock_pips, mod, cst, db): portmap = db.grid[dbrow][dbcol].bels[bel[:-1]].portmap for port, wname in portmap.items(): pll.portmap[port] = f"R{row}C{col}_{wname}" + elif typ.startswith("BSRAM"): + name = f"BSRAM_{idx}" + pll = mod.primitives.setdefault(name, codegen.Primitive("BSRAM", name)) + for paramval in flags: + param, _, val = paramval.partition('=') + pll.params[param] = val + portmap = db.grid[dbrow][dbcol].bels[bel].portmap + for port, wname in portmap.items(): + pll.portmap[port] = f"R{row}C{col}_{wname}" elif typ == "ALU": #print(flags) kind, = flags # ALU only have one flag @@ -916,6 +947,7 @@ def tile2verilog(dbrow, dbcol, bels, pips, clock_pips, mod, cst, db): elif kind == "0": alu.portmap['I0'] = f"R{row}C{col}_B{idx}" alu.portmap['I1'] = f"R{row}C{col}_D{idx}" + alu.portmap['I3'] = f"R{row}C{col}_A{idx}" elif kind == "C2L": alu.portmap['I0'] = f"R{row}C{col}_B{idx}" alu.portmap['I1'] = f"R{row}C{col}_D{idx}" diff --git a/examples/himbaechel/DPB-image-rom.v b/examples/himbaechel/DPB-image-rom.v new file mode 120000 index 00000000..907c49ad --- /dev/null +++ b/examples/himbaechel/DPB-image-rom.v @@ -0,0 +1 @@ +pROM-image-rom.v \ No newline at end of file diff --git a/examples/himbaechel/DPB-video-ram.v b/examples/himbaechel/DPB-video-ram.v new file mode 100644 index 00000000..23418108 --- /dev/null +++ b/examples/himbaechel/DPB-video-ram.v @@ -0,0 +1,51 @@ +`default_nettype none +module video_ram( + input wire clk, + input wire reset, + input wire write_clk, + input wire write_reset, + input wire write_ce, + input wire read_wre, + input wire [10:0] write_ad, + input wire [7:0] write_data, + input wire [10:0] read_ad, + output wire [7:0] read_data +); + + wire gnd, vcc; + assign gnd = 1'b0; + assign vcc = 1'b1; + + wire [7:0] dummy; + + DPB mem( + .DOB({dummy, read_data}), + .DIA({{8{gnd}}, write_data}), + .DIB({16{gnd}}), + .ADA({write_ad, gnd, gnd, gnd}), + .ADB({ read_ad, gnd, gnd, gnd}), + .CLKA(write_clk), + .CLKB(clk), + .OCEA(vcc), + .OCEB(vcc), + .CEA(write_ce), + .CEB(vcc), + .WREA(vcc), + .WREB(read_wre), + .BLKSELA(3'b000), + .BLKSELB(3'b000), + .RESETA(write_reset), + .RESETB(reset) + ); + defparam mem.READ_MODE0 = 1'b1; + defparam mem.READ_MODE1 = 1'b1; + defparam mem.WRITE_MODE0 = 2'b01; + defparam mem.WRITE_MODE1 = 2'b01; + defparam mem.BIT_WIDTH_0 = 8; + defparam mem.BIT_WIDTH_1 = 8; + defparam mem.BLK_SEL_0 = 3'b000; + defparam mem.BLK_SEL_1 = 3'b000; + defparam mem.RESET_MODE = "SYNC"; +`include "img-video-ram.vh" +endmodule + diff --git a/examples/himbaechel/DPB.v b/examples/himbaechel/DPB.v new file mode 100644 index 00000000..34bfcd71 --- /dev/null +++ b/examples/himbaechel/DPB.v @@ -0,0 +1,175 @@ +`default_nettype none +(* top *) +module top +( + input wire rst_i, + input wire key_i, + input wire clk, + + output wire LCD_CLK, + output wire LCD_HYNC, + output wire LCD_SYNC, + output wire LCD_DEN, + output wire [4:0] LCD_R, + output wire [5:0] LCD_G, + output wire [4:0] LCD_B +); + + wire rst = rst_i ^ `INV_BTN; + wire key = key_i ^ `INV_BTN; + wire pixel_clk; + wire write_clk; + wire gnd; + assign gnd = 1'b0; + + rPLL pll( + .CLKOUT(pixel_clk), // 9MHz + .CLKOUTD(write_clk), + .CLKIN(clk), + .CLKFB(gnd), + .RESET(!rst), + .RESET_P(!rst), + .FBDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .IDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .ODSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .DUTYDA({gnd, gnd, gnd, gnd}), + .PSDA({gnd, gnd, gnd, gnd}), + .FDLY({gnd, gnd, gnd, gnd}) + ); + defparam pll.DEVICE = `PLL_DEVICE; + defparam pll.FCLKIN = `PLL_FCLKIN; + defparam pll.FBDIV_SEL = `PLL_FBDIV_SEL_LCD; + defparam pll.IDIV_SEL = `PLL_IDIV_SEL_LCD; + defparam pll.ODIV_SEL = `PLL_ODIV_SEL; + defparam pll.CLKFB_SEL="internal"; + defparam pll.CLKOUTD3_SRC="CLKOUT"; + defparam pll.CLKOUTD_BYPASS="false"; + defparam pll.CLKOUTD_SRC="CLKOUT"; + defparam pll.CLKOUTP_BYPASS="false"; + defparam pll.CLKOUTP_DLY_STEP=0; + defparam pll.CLKOUTP_FT_DIR=1'b1; + defparam pll.CLKOUT_BYPASS="false"; + defparam pll.CLKOUT_DLY_STEP=0; + defparam pll.CLKOUT_FT_DIR=1'b1; + defparam pll.DUTYDA_SEL="1000"; + defparam pll.DYN_DA_EN="false"; + defparam pll.DYN_FBDIV_SEL="false"; + defparam pll.DYN_IDIV_SEL="false"; + defparam pll.DYN_ODIV_SEL="false"; + defparam pll.DYN_SDIV_SEL=128; + defparam pll.PSDA_SEL="0000"; + + assign LCD_CLK = pixel_clk; + + reg [15:0] pixel_count; + reg [15:0] line_count; + + /* 480x272 4.3" LCD with SC7283 driver, pixel freq = 9MHz */ + localparam VBackPorch = 16'd12; + localparam VPulse = 16'd4; + localparam HightPixel = 16'd272; + localparam VFrontPorch= 16'd8; + + localparam HBackPorch = 16'd43; + localparam HPulse = 16'd4; + localparam WidthPixel = 16'd480; + localparam HFrontPorch= 16'd8; + + + localparam PixelForHS = WidthPixel + HBackPorch + HFrontPorch; + localparam LineForVS = HightPixel + VBackPorch + VFrontPorch; + + always @(posedge pixel_clk or negedge rst)begin + if (!rst) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else if (pixel_count == PixelForHS) begin + pixel_count <= 16'b0; + line_count <= line_count + 1'b1; + end + else if (line_count == LineForVS) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else begin + pixel_count <= pixel_count + 1'b1; + end + end + + + assign LCD_HYNC = ((pixel_count >= HPulse) && (pixel_count <= (PixelForHS - HFrontPorch))) ? 1'b0 : 1'b1; + assign LCD_SYNC = (((line_count >= VPulse) && (line_count <= (LineForVS - 0)))) ? 1'b0 : 1'b1; + + assign LCD_DEN = ((pixel_count >= HBackPorch) && + (pixel_count <= PixelForHS - HFrontPorch) && + (line_count >= VBackPorch) && + (line_count <= LineForVS - VFrontPorch - 1)) ? 1'b1 : 1'b0; + + wire [7:0] rom_data; + reg [10:0] read_addr; + reg [16:0] write_addr; + reg write_ce; + + image_rom image( + .clk(pixel_clk), + .reset(!rst), + .ad(write_addr[16:5]), + .data(rom_data) + ); + + wire [7:0] dout; + + video_ram vmem( + .clk(pixel_clk), + .write_clk(write_clk), + .reset(!rst), + .write_reset(!rst), + .write_ce(write_ce), + .read_wre(!key), + .read_ad(read_addr), + .read_data(dout), + .write_ad(write_addr[15:5]), + .write_data(rom_data) + ); + + always @(posedge write_clk or negedge rst ) begin + if (!rst) begin + write_ce <= 1; + write_addr <= 0; + end else begin + write_addr <= write_addr + 1; + end + end + +`define START_X 16'd160 +`define STOP_X (`START_X + 16'd256) +`define START_Y 16'd18 +`define STOP_Y (`START_Y + 16'd256) + + wire [7:0] vmem_start_col; + wire [7:0] vmem_start_row; + assign vmem_start_col = pixel_count - `START_X; + assign vmem_start_row = line_count - `START_Y; + + always @(negedge pixel_clk) begin + read_addr <= {vmem_start_row[7:2], vmem_start_col[7:2]}; + end + + wire is_out_x = pixel_count < `START_X || pixel_count >= `STOP_X; + wire is_out_y = line_count < `START_Y || line_count >= `STOP_Y; + + reg [15:0] color; + always @(posedge pixel_clk) begin + if (is_out_x || is_out_y) begin + color <= line_count + pixel_count; + end else begin + color <= {dout, dout}; + end + end + + assign LCD_R = color[4:0]; + assign LCD_G = color[5:0]; + assign LCD_B = color[4:0]; +endmodule + diff --git a/examples/himbaechel/DPB16-image-rom.v b/examples/himbaechel/DPB16-image-rom.v new file mode 100644 index 00000000..7f1e00d6 --- /dev/null +++ b/examples/himbaechel/DPB16-image-rom.v @@ -0,0 +1,44 @@ +`default_nettype none +module image_rom( + input wire clk, + input wire reset, + input wire [10:0] ad, + output wire [15:0] data +); + + wire gnd, vcc; + assign gnd = 1'b0; + assign vcc = 1'b1; + + wire [15:0] dummy [1:0]; + wire [15:0] data_mux [1:0]; + assign data = data_mux[ad[10]]; + + pROM rom( + .AD({ad[9:0], gnd, gnd, gnd, gnd}), + .DO({dummy[0], data_mux[0]}), + .CLK(clk), + .OCE(vcc), + .CE(vcc), + .RESET(reset) + ); + defparam rom.READ_MODE = 1'b1; + defparam rom.BIT_WIDTH = 16; + defparam rom.RESET_MODE = "SYNC"; +`include "img-rom.vh" + + pROM rom1( + .AD({ad[9:0], gnd, gnd, gnd, gnd}), + .DO({dummy[1], data_mux[1]}), + .CLK(clk), + .OCE(vcc), + .CE(vcc), + .RESET(reset) + ); + defparam rom1.READ_MODE = 1'b1; + defparam rom1.BIT_WIDTH = 16; + defparam rom1.RESET_MODE = "SYNC"; +`include "img-rom1.vh" + +endmodule + diff --git a/examples/himbaechel/DPB16-video-ram.v b/examples/himbaechel/DPB16-video-ram.v new file mode 100644 index 00000000..30e8435c --- /dev/null +++ b/examples/himbaechel/DPB16-video-ram.v @@ -0,0 +1,51 @@ +`default_nettype none +module video_ram( + input wire clk, + input wire reset, + input wire write_clk, + input wire write_reset, + input wire write_ce, + input wire read_wre, + input wire [9:0] write_ad, + input wire [15:0] write_data, + input wire [9:0] read_ad, + output wire [15:0] read_data +); + + wire gnd, vcc; + assign gnd = 1'b0; + assign vcc = 1'b1; + + wire [15:0] dummy; + + DPB mem( + .DOB({read_data}), + .DIA({write_data}), + .DIB({16{gnd}}), + .ADA({write_ad, gnd, gnd, vcc, vcc}), + .ADB({ read_ad, gnd, gnd, vcc, vcc}), + .CLKA(write_clk), + .CLKB(clk), + .OCEA(gnd), + .OCEB(gnd), + .CEA(write_ce), + .CEB(vcc), + .WREA(vcc), + .WREB(read_wre), + .BLKSELA(3'b000), + .BLKSELB(3'b000), + .RESETA(write_reset), + .RESETB(reset) + ); + defparam mem.READ_MODE0 = 1'b0; + defparam mem.READ_MODE1 = 1'b0; + defparam mem.WRITE_MODE0 = 2'b01; + defparam mem.WRITE_MODE1 = 2'b01; + defparam mem.BIT_WIDTH_0 = 16; + defparam mem.BIT_WIDTH_1 = 16; + defparam mem.BLK_SEL_0 = 3'b000; + defparam mem.BLK_SEL_1 = 3'b000; + defparam mem.RESET_MODE = "SYNC"; +`include "img-video-ram.vh" +endmodule + diff --git a/examples/himbaechel/DPB16.v b/examples/himbaechel/DPB16.v new file mode 100644 index 00000000..0cca5396 --- /dev/null +++ b/examples/himbaechel/DPB16.v @@ -0,0 +1,177 @@ +`default_nettype none +(* top *) +module top +( + input wire rst_i, + input wire key_i, + input wire clk, + + output wire LCD_CLK, + output wire LCD_HYNC, + output wire LCD_SYNC, + output wire LCD_DEN, + output wire [4:0] LCD_R, + output wire [5:0] LCD_G, + output wire [4:0] LCD_B +); + + wire rst = rst_i ^ `INV_BTN; + wire key = key_i ^ `INV_BTN; + wire pixel_clk; + wire write_clk; + wire gnd; + assign gnd = 1'b0; + + rPLL pll( + .CLKOUT(pixel_clk), // 9MHz + .CLKOUTD(write_clk), + .CLKIN(clk), + .CLKFB(gnd), + .RESET(!rst), + .RESET_P(!rst), + .FBDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .IDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .ODSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .DUTYDA({gnd, gnd, gnd, gnd}), + .PSDA({gnd, gnd, gnd, gnd}), + .FDLY({gnd, gnd, gnd, gnd}) + ); + defparam pll.DEVICE = `PLL_DEVICE; + defparam pll.FCLKIN = `PLL_FCLKIN; + defparam pll.FBDIV_SEL = `PLL_FBDIV_SEL_LCD; + defparam pll.IDIV_SEL = `PLL_IDIV_SEL_LCD; + defparam pll.ODIV_SEL = `PLL_ODIV_SEL; + defparam pll.CLKFB_SEL="internal"; + defparam pll.CLKOUTD3_SRC="CLKOUT"; + defparam pll.CLKOUTD_BYPASS="false"; + defparam pll.CLKOUTD_SRC="CLKOUT"; + defparam pll.CLKOUTP_BYPASS="false"; + defparam pll.CLKOUTP_DLY_STEP=0; + defparam pll.CLKOUTP_FT_DIR=1'b1; + defparam pll.CLKOUT_BYPASS="false"; + defparam pll.CLKOUT_DLY_STEP=0; + defparam pll.CLKOUT_FT_DIR=1'b1; + defparam pll.DUTYDA_SEL="1000"; + defparam pll.DYN_DA_EN="false"; + defparam pll.DYN_FBDIV_SEL="false"; + defparam pll.DYN_IDIV_SEL="false"; + defparam pll.DYN_ODIV_SEL="false"; + defparam pll.DYN_SDIV_SEL=128; + defparam pll.PSDA_SEL="0000"; + + assign LCD_CLK = pixel_clk; + + reg [15:0] pixel_count; + reg [15:0] line_count; + + /* 480x272 4.3" LCD with SC7283 driver, pixel freq = 9MHz */ + localparam VBackPorch = 16'd12; + localparam VPulse = 16'd4; + localparam HightPixel = 16'd272; + localparam VFrontPorch= 16'd8; + + localparam HBackPorch = 16'd43; + localparam HPulse = 16'd4; + localparam WidthPixel = 16'd480; + localparam HFrontPorch= 16'd8; + + + localparam PixelForHS = WidthPixel + HBackPorch + HFrontPorch; + localparam LineForVS = HightPixel + VBackPorch + VFrontPorch; + + always @(posedge pixel_clk or negedge rst)begin + if (!rst) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else if (pixel_count == PixelForHS) begin + pixel_count <= 16'b0; + line_count <= line_count + 1'b1; + end + else if (line_count == LineForVS) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else begin + pixel_count <= pixel_count + 1'b1; + end + end + + + assign LCD_HYNC = ((pixel_count >= HPulse) && (pixel_count <= (PixelForHS - HFrontPorch))) ? 1'b0 : 1'b1; + assign LCD_SYNC = (((line_count >= VPulse) && (line_count <= (LineForVS - 0)))) ? 1'b0 : 1'b1; + + assign LCD_DEN = ((pixel_count >= HBackPorch) && + (pixel_count <= PixelForHS - HFrontPorch) && + (line_count >= VBackPorch) && + (line_count <= LineForVS - VFrontPorch - 1)) ? 1'b1 : 1'b0; + + wire [15:0] rom_data; + reg [10:0] read_addr; + reg [16:0] write_addr; + reg write_ce; + + image_rom image( + .clk(pixel_clk), + .reset(!rst), + .ad(write_addr[16:6]), + .data(rom_data) + ); + + wire [15:0] dout; + + video_ram vmem( + .clk(pixel_clk), + .write_clk(write_clk), + .reset(!rst), + .write_reset(!rst), + .write_ce(write_ce), + .read_wre(!key), + .read_ad(read_addr[10:1]), + .read_data(dout), + .write_ad(write_addr[15:6]), + .write_data(rom_data) + ); + + always @(posedge write_clk or negedge rst ) begin + if (!rst) begin + write_ce <= 1; + write_addr <= 0; + end else begin + write_addr <= write_addr + 1; + end + end + +`define START_X 16'd160 +`define STOP_X (`START_X + 16'd256) +`define START_Y 16'd18 +`define STOP_Y (`START_Y + 16'd256) + + wire [7:0] vmem_start_col; + wire [7:0] vmem_start_row; + assign vmem_start_col = pixel_count - `START_X; + assign vmem_start_row = line_count - `START_Y; + + always @(negedge pixel_clk) begin + if (pixel_count[2]) begin + read_addr <= {vmem_start_row[6:2], vmem_start_col[7:2]}; + end + end + + wire is_out_x = pixel_count < `START_X || pixel_count >= `STOP_X; + wire is_out_y = line_count < `START_Y || line_count >= `STOP_Y; + + reg [15:0] color; + always @(posedge pixel_clk) begin + if (is_out_x || is_out_y) begin + color <= line_count + pixel_count; + end else begin + color <= dout; + end + end + + assign LCD_R = color[4:0]; + assign LCD_G = color[5:0]; + assign LCD_B = color[4:0]; +endmodule + diff --git a/examples/himbaechel/DPX9B-image-rom.v b/examples/himbaechel/DPX9B-image-rom.v new file mode 120000 index 00000000..32b94c73 --- /dev/null +++ b/examples/himbaechel/DPX9B-image-rom.v @@ -0,0 +1 @@ +pROMX9-image-rom.v \ No newline at end of file diff --git a/examples/himbaechel/DPX9B-video-ram.v b/examples/himbaechel/DPX9B-video-ram.v new file mode 100644 index 00000000..72906d52 --- /dev/null +++ b/examples/himbaechel/DPX9B-video-ram.v @@ -0,0 +1,51 @@ +`default_nettype none +module video_ram( + input wire clk, + input wire reset, + input wire write_clk, + input wire write_reset, + input wire write_ce, + input wire read_wre, + input wire [10:0] write_ad, + input wire [8:0] write_data, + input wire [10:0] read_ad, + output wire [8:0] read_data +); + + wire gnd, vcc; + assign gnd = 1'b0; + assign vcc = 1'b1; + + wire [8:0] dummy; + + DPX9B mem( + .DOB({dummy, read_data}), + .DIA({{9{gnd}},write_data}), + .DIB({18{gnd}}), + .ADA({write_ad, gnd, gnd, gnd}), + .ADB({ read_ad, gnd, gnd, gnd}), + .CLKA(write_clk), + .CLKB(clk), + .OCEA(vcc), + .OCEB(vcc), + .CEA(write_ce), + .CEB(vcc), + .WREA(vcc), + .WREB(read_wre), + .BLKSELA(3'b000), + .BLKSELB(3'b000), + .RESETA(write_reset), + .RESETB(reset) + ); + defparam mem.READ_MODE0 = 1'b1; + defparam mem.READ_MODE1 = 1'b1; + defparam mem.WRITE_MODE0 = 2'b01; + defparam mem.WRITE_MODE1 = 2'b01; + defparam mem.BIT_WIDTH_0 = 9; + defparam mem.BIT_WIDTH_1 = 9; + defparam mem.BLK_SEL_0 = 3'b000; + defparam mem.BLK_SEL_1 = 3'b000; + defparam mem.RESET_MODE = "SYNC"; +`include "img-video-ram1.vh" +endmodule + diff --git a/examples/himbaechel/DPX9B.v b/examples/himbaechel/DPX9B.v new file mode 100644 index 00000000..7585d225 --- /dev/null +++ b/examples/himbaechel/DPX9B.v @@ -0,0 +1,175 @@ +`default_nettype none +(* top *) +module top +( + input wire rst_i, + input wire key_i, + input wire clk, + + output wire LCD_CLK, + output wire LCD_HYNC, + output wire LCD_SYNC, + output wire LCD_DEN, + output wire [4:0] LCD_R, + output wire [5:0] LCD_G, + output wire [4:0] LCD_B +); + + wire rst = rst_i ^ `INV_BTN; + wire key = key_i ^ `INV_BTN; + wire pixel_clk; + wire write_clk; + wire gnd; + assign gnd = 1'b0; + + rPLL pll( + .CLKOUT(pixel_clk), // 9MHz + .CLKOUTD(write_clk), + .CLKIN(clk), + .CLKFB(gnd), + .RESET(!rst), + .RESET_P(!rst), + .FBDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .IDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .ODSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .DUTYDA({gnd, gnd, gnd, gnd}), + .PSDA({gnd, gnd, gnd, gnd}), + .FDLY({gnd, gnd, gnd, gnd}) + ); + defparam pll.DEVICE = `PLL_DEVICE; + defparam pll.FCLKIN = `PLL_FCLKIN; + defparam pll.FBDIV_SEL = `PLL_FBDIV_SEL_LCD; + defparam pll.IDIV_SEL = `PLL_IDIV_SEL_LCD; + defparam pll.ODIV_SEL = `PLL_ODIV_SEL; + defparam pll.CLKFB_SEL="internal"; + defparam pll.CLKOUTD3_SRC="CLKOUT"; + defparam pll.CLKOUTD_BYPASS="false"; + defparam pll.CLKOUTD_SRC="CLKOUT"; + defparam pll.CLKOUTP_BYPASS="false"; + defparam pll.CLKOUTP_DLY_STEP=0; + defparam pll.CLKOUTP_FT_DIR=1'b1; + defparam pll.CLKOUT_BYPASS="false"; + defparam pll.CLKOUT_DLY_STEP=0; + defparam pll.CLKOUT_FT_DIR=1'b1; + defparam pll.DUTYDA_SEL="1000"; + defparam pll.DYN_DA_EN="false"; + defparam pll.DYN_FBDIV_SEL="false"; + defparam pll.DYN_IDIV_SEL="false"; + defparam pll.DYN_ODIV_SEL="false"; + defparam pll.DYN_SDIV_SEL=128; + defparam pll.PSDA_SEL="0000"; + + assign LCD_CLK = pixel_clk; + + reg [15:0] pixel_count; + reg [15:0] line_count; + + /* 480x272 4.3" LCD with SC7283 driver, pixel freq = 9MHz */ + localparam VBackPorch = 16'd12; + localparam VPulse = 16'd4; + localparam HightPixel = 16'd272; + localparam VFrontPorch= 16'd8; + + localparam HBackPorch = 16'd43; + localparam HPulse = 16'd4; + localparam WidthPixel = 16'd480; + localparam HFrontPorch= 16'd8; + + + localparam PixelForHS = WidthPixel + HBackPorch + HFrontPorch; + localparam LineForVS = HightPixel + VBackPorch + VFrontPorch; + + always @(posedge pixel_clk or negedge rst)begin + if (!rst) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else if (pixel_count == PixelForHS) begin + pixel_count <= 16'b0; + line_count <= line_count + 1'b1; + end + else if (line_count == LineForVS) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else begin + pixel_count <= pixel_count + 1'b1; + end + end + + + assign LCD_HYNC = ((pixel_count >= HPulse) && (pixel_count <= (PixelForHS - HFrontPorch))) ? 1'b0 : 1'b1; + assign LCD_SYNC = (((line_count >= VPulse) && (line_count <= (LineForVS - 0)))) ? 1'b0 : 1'b1; + + assign LCD_DEN = ((pixel_count >= HBackPorch) && + (pixel_count <= PixelForHS - HFrontPorch) && + (line_count >= VBackPorch) && + (line_count <= LineForVS - VFrontPorch - 1)) ? 1'b1 : 1'b0; + + wire [8:0] rom_data; + reg [10:0] read_addr; + reg [16:0] write_addr; + reg write_ce; + + image_rom image( + .clk(pixel_clk), + .reset(!rst), + .ad(write_addr[16:5]), + .data(rom_data) + ); + + wire [8:0] dout; + + video_ram vmem( + .clk(pixel_clk), + .write_clk(write_clk), + .reset(!rst), + .write_reset(!rst), + .write_ce(write_ce), + .read_wre(!key), + .read_ad(read_addr), + .read_data(dout), + .write_ad(write_addr[15:5]), + .write_data(rom_data) + ); + + always @(posedge write_clk or negedge rst ) begin + if (!rst) begin + write_ce <= 1; + write_addr <= 0; + end else begin + write_addr <= write_addr + 1; + end + end + +`define START_X 16'd160 +`define STOP_X (`START_X + 16'd256) +`define START_Y 16'd18 +`define STOP_Y (`START_Y + 16'd256) + + wire [7:0] vmem_start_col; + wire [7:0] vmem_start_row; + assign vmem_start_col = pixel_count - `START_X; + assign vmem_start_row = line_count - `START_Y; + + always @(negedge pixel_clk) begin + read_addr <= {vmem_start_row[7:2], vmem_start_col[7:2]}; + end + + wire is_out_x = pixel_count < `START_X || pixel_count >= `STOP_X; + wire is_out_y = line_count < `START_Y || line_count >= `STOP_Y; + + reg [18:0] color; + always @(posedge pixel_clk) begin + if (is_out_x || is_out_y) begin + color <= {line_count, 3'b000} + {pixel_count, 3'b000}; + end else begin + color <= dout; + end + end + + assign LCD_R = color[8:4]; + assign LCD_G = color[8:3]; + assign LCD_B = color[8:4]; +endmodule + diff --git a/examples/himbaechel/DPX9B18-image-rom.v b/examples/himbaechel/DPX9B18-image-rom.v new file mode 100644 index 00000000..d31f4f00 --- /dev/null +++ b/examples/himbaechel/DPX9B18-image-rom.v @@ -0,0 +1,44 @@ +`default_nettype none +module image_rom( + input wire clk, + input wire reset, + input wire [10:0] ad, + output wire [17:0] data +); + + wire gnd, vcc; + assign gnd = 1'b0; + assign vcc = 1'b1; + + wire [17:0] dummy_w [1:0]; + wire [17:0] data_w [1:0]; + assign data = data_w[ad[10]]; + + pROMX9 rom2( + .AD({ad[9:0], gnd, gnd, gnd, gnd}), + .DO({dummy_w[0], data_w[1]}), + .CLK(clk), + .OCE(vcc), + .CE(vcc), + .RESET(reset) + ); + defparam rom2.READ_MODE = 1'b1; + defparam rom2.BIT_WIDTH = 18; + defparam rom2.RESET_MODE = "SYNC"; +`include "img-rom2.vh" + + pROMX9 rom3( + .AD({ad[9:0], gnd, gnd, gnd, gnd}), + .DO({dummy_w[1], data_w[0]}), + .CLK(clk), + .OCE(vcc), + .CE(vcc), + .RESET(reset) + ); + defparam rom3.READ_MODE = 1'b1; + defparam rom3.BIT_WIDTH = 18; + defparam rom3.RESET_MODE = "SYNC"; +`include "img-rom3.vh" + +endmodule + diff --git a/examples/himbaechel/DPX9B18-video-ram.v b/examples/himbaechel/DPX9B18-video-ram.v new file mode 100644 index 00000000..0c80f4d6 --- /dev/null +++ b/examples/himbaechel/DPX9B18-video-ram.v @@ -0,0 +1,51 @@ +`default_nettype none +module video_ram( + input wire clk, + input wire reset, + input wire write_clk, + input wire write_reset, + input wire write_ce, + input wire read_wre, + input wire [9:0] write_ad, + input wire [17:0] write_data, + input wire [9:0] read_ad, + output wire [17:0] read_data +); + + wire gnd, vcc; + assign gnd = 1'b0; + assign vcc = 1'b1; + + wire [17:0] dummy; + + DPX9B mem( + .DOB({read_data}), + .DIA({write_data}), + .DIB({18{gnd}}), + .ADA({write_ad, gnd, gnd, vcc, vcc}), + .ADB({ read_ad, gnd, gnd, vcc, vcc}), + .CLKA(write_clk), + .CLKB(clk), + .OCEA(gnd), + .OCEB(gnd), + .CEA(write_ce), + .CEB(vcc), + .WREA(vcc), + .WREB(read_wre), + .BLKSELA(3'b000), + .BLKSELB(3'b000), + .RESETA(write_reset), + .RESETB(reset) + ); + defparam mem.READ_MODE0 = 1'b0; + defparam mem.READ_MODE1 = 1'b0; + defparam mem.WRITE_MODE0 = 2'b01; + defparam mem.WRITE_MODE1 = 2'b01; + defparam mem.BIT_WIDTH_0 = 18; + defparam mem.BIT_WIDTH_1 = 18; + defparam mem.BLK_SEL_0 = 3'b000; + defparam mem.BLK_SEL_1 = 3'b000; + defparam mem.RESET_MODE = "SYNC"; +`include "img-video-ram1.vh" +endmodule + diff --git a/examples/himbaechel/DPX9B18.v b/examples/himbaechel/DPX9B18.v new file mode 100644 index 00000000..287a9981 --- /dev/null +++ b/examples/himbaechel/DPX9B18.v @@ -0,0 +1,176 @@ +`default_nettype none +(* top *) +module top +( + input wire rst_i, + input wire key_i, + input wire clk, + + output wire LCD_CLK, + output wire LCD_HYNC, + output wire LCD_SYNC, + output wire LCD_DEN, + output wire [4:0] LCD_R, + output wire [5:0] LCD_G, + output wire [4:0] LCD_B +); + + wire rst = rst_i ^ `INV_BTN; + wire pixel_clk; + wire write_clk; + wire gnd; + assign gnd = 1'b0; + + rPLL pll( + .CLKOUT(pixel_clk), // 9MHz + .CLKOUTD(write_clk), + .CLKIN(clk), + .CLKFB(gnd), + .RESET(!rst), + .RESET_P(!rst), + .FBDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .IDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .ODSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .DUTYDA({gnd, gnd, gnd, gnd}), + .PSDA({gnd, gnd, gnd, gnd}), + .FDLY({gnd, gnd, gnd, gnd}) + ); + defparam pll.DEVICE = `PLL_DEVICE; + defparam pll.FCLKIN = `PLL_FCLKIN; + defparam pll.FBDIV_SEL = `PLL_FBDIV_SEL_LCD; + defparam pll.IDIV_SEL = `PLL_IDIV_SEL_LCD; + defparam pll.ODIV_SEL = `PLL_ODIV_SEL; + defparam pll.CLKFB_SEL="internal"; + defparam pll.CLKOUTD3_SRC="CLKOUT"; + defparam pll.CLKOUTD_BYPASS="false"; + defparam pll.CLKOUTD_SRC="CLKOUT"; + defparam pll.CLKOUTP_BYPASS="false"; + defparam pll.CLKOUTP_DLY_STEP=0; + defparam pll.CLKOUTP_FT_DIR=1'b1; + defparam pll.CLKOUT_BYPASS="false"; + defparam pll.CLKOUT_DLY_STEP=0; + defparam pll.CLKOUT_FT_DIR=1'b1; + defparam pll.DUTYDA_SEL="1000"; + defparam pll.DYN_DA_EN="false"; + defparam pll.DYN_FBDIV_SEL="false"; + defparam pll.DYN_IDIV_SEL="false"; + defparam pll.DYN_ODIV_SEL="false"; + defparam pll.DYN_SDIV_SEL=128; + defparam pll.PSDA_SEL="0000"; + + assign LCD_CLK = pixel_clk; + + reg [15:0] pixel_count; + reg [15:0] line_count; + + /* 480x272 4.3" LCD with SC7283 driver, pixel freq = 9MHz */ + localparam VBackPorch = 16'd12; + localparam VPulse = 16'd4; + localparam HightPixel = 16'd272; + localparam VFrontPorch= 16'd8; + + localparam HBackPorch = 16'd43; + localparam HPulse = 16'd4; + localparam WidthPixel = 16'd480; + localparam HFrontPorch= 16'd8; + + + localparam PixelForHS = WidthPixel + HBackPorch + HFrontPorch; + localparam LineForVS = HightPixel + VBackPorch + VFrontPorch; + + always @(posedge pixel_clk or negedge rst)begin + if (!rst) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else if (pixel_count == PixelForHS) begin + pixel_count <= 16'b0; + line_count <= line_count + 1'b1; + end + else if (line_count == LineForVS) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else begin + pixel_count <= pixel_count + 1'b1; + end + end + + + assign LCD_HYNC = ((pixel_count >= HPulse) && (pixel_count <= (PixelForHS - HFrontPorch))) ? 1'b0 : 1'b1; + assign LCD_SYNC = (((line_count >= VPulse) && (line_count <= (LineForVS - 0)))) ? 1'b0 : 1'b1; + + assign LCD_DEN = ((pixel_count >= HBackPorch) && + (pixel_count <= PixelForHS - HFrontPorch) && + (line_count >= VBackPorch) && + (line_count <= LineForVS - VFrontPorch - 1)) ? 1'b1 : 1'b0; + + wire [17:0] rom_data; + reg [10:0] read_addr; + reg [16:0] write_addr; + reg write_ce; + + image_rom image( + .clk(pixel_clk), + .reset(!rst), + .ad(write_addr[16:6]), + .data(rom_data) + ); + + wire [17:0] dout; + + video_ram vmem( + .clk(pixel_clk), + .write_clk(write_clk), + .reset(!rst), + .write_reset(!rst), + .write_ce(write_ce), + .read_wre(!key_i), + .read_ad(read_addr[10:1]), + .read_data(dout), + .write_ad(write_addr[15:6]), + .write_data(rom_data) + ); + + always @(posedge write_clk or negedge rst ) begin + if (!rst) begin + write_ce <= 1; + write_addr <= 0; + end else begin + write_addr <= write_addr + 1; + end + end + +`define START_X 16'd160 +`define STOP_X (`START_X + 16'd256) +`define START_Y 16'd18 +`define STOP_Y (`START_Y + 16'd256) + + wire [7:0] vmem_start_col; + wire [7:0] vmem_start_row; + assign vmem_start_col = pixel_count - `START_X; + assign vmem_start_row = line_count - `START_Y; + + always @(negedge pixel_clk) begin + if (pixel_count[2]) begin + read_addr <= {vmem_start_row[6:2], vmem_start_col[7:2]}; + end + end + + wire is_out_x = pixel_count < `START_X || pixel_count >= `STOP_X; + wire is_out_y = line_count < `START_Y || line_count >= `STOP_Y; + + reg [18:0] color; + always @(posedge pixel_clk) begin + if (is_out_x || is_out_y) begin + color <= line_count + pixel_count; + end else begin + color <= dout; + end + end + + assign LCD_R = color[17:13]; + assign LCD_G = color[17:12]; + assign LCD_B = color[17:13]; +endmodule + diff --git a/examples/himbaechel/Makefile.himbaechel b/examples/himbaechel/Makefile.himbaechel index 6b6fa623..197c2431 100644 --- a/examples/himbaechel/Makefile.himbaechel +++ b/examples/himbaechel/Makefile.himbaechel @@ -1,8 +1,6 @@ YOSYS ?= yosys NEXTPNR ?= nextpnr-himbaechel -HIMBAECHEL_OUT ?= ./himbaechel-out - .DEFAULT_GOAL := all all: \ @@ -11,22 +9,34 @@ all: \ oddr-elvds-tangnano20k.fs pll-nanolcd-tangnano20k.fs attosoc-tangnano20k.fs \ oser4-tangnano20k.fs ovideo-tangnano20k.fs oser8-tangnano20k.fs oser10-tangnano20k.fs \ ides4-tangnano20k.fs ivideo-tangnano20k.fs ides8-tangnano20k.fs ides10-tangnano20k.fs \ + bsram-pROM-tangnano20k.fs bsram-SDPB-tangnano20k.fs bsram-SP-tangnano20k.fs \ + bsram-DPB-tangnano20k.fs bsram-pROMX9-tangnano20k.fs bsram-SDPX9B-tangnano20k.fs \ + bsram-SPX9-tangnano20k.fs bsram-DPX9B-tangnano20k.fs \ \ blinky-primer20k.fs shift-primer20k.fs blinky-tbuf-primer20k.fs blinky-oddr-primer20k.fs \ blinky-osc-primer20k.fs tlvds-primer20k.fs elvds-primer20k.fs oddr-tlvds-primer20k.fs \ oddr-elvds-primer20k.fs pll-nanolcd-primer20k.fs attosoc-primer20k.fs \ oser4-primer20k.fs ovideo-primer20k.fs oser8-primer20k.fs oser10-primer20k.fs \ ides4-primer20k.fs ivideo-primer20k.fs ides8-primer20k.fs ides10-primer20k.fs \ + bsram-pROM-primer20k.fs bsram-SDPB-primer20k.fs bsram-SP-primer20k.fs \ + bsram-DPB-primer20k.fs bsram-pROMX9-primer20k.fs bsram-SDPX9B-primer20k.fs \ + bsram-SPX9-primer20k.fs bsram-DPX9B-primer20k.fs \ \ blinky-tangnano.fs shift-tangnano.fs blinky-tbuf-tangnano.fs blinky-oddr-tangnano.fs \ blinky-osc-tangnano.fs elvds-tangnano.fs oddr-elvds-tangnano.fs pll-nanolcd-tangnano.fs \ oser4-tangnano.fs ovideo-tangnano.fs oser8-tangnano.fs oser10-tangnano.fs \ ides4-tangnano.fs ivideo-tangnano.fs ides8-tangnano.fs ides10-tangnano.fs \ + bsram-pROM-tangnano.fs bsram-SDPB-tangnano.fs bsram-DPB-tangnano.fs \ + bsram-SP-tangnano.fs bsram-pROMX9-tangnano.fs bsram-SDPX9B-tangnano.fs \ + bsram-SPX9-tangnano.fs bsram-DPX9B-tangnano.fs \ \ blinky-tangnano1k.fs shift-tangnano1k.fs blinky-tbuf-tangnano1k.fs blinky-oddr-tangnano1k.fs \ blinky-osc-tangnano1k.fs elvds-tangnano1k.fs oddr-elvds-tangnano1k.fs pll-nanolcd-tangnano1k.fs \ oser4-tangnano1k.fs ovideo-tangnano1k.fs oser8-tangnano1k.fs oser10-tangnano1k.fs \ ides4-tangnano1k.fs ivideo-tangnano1k.fs ides8-tangnano1k.fs ides10-tangnano1k.fs \ + bsram-pROM-tangnano1k.fs bsram-SDPB-tangnano1k.fs bsram-DPB16-tangnano1k.fs \ + bsram-SP-tangnano1k.fs bsram-pROMX9-tangnano1k.fs bsram-SDPX9B-tangnano1k.fs \ + bsram-SPX9-tangnano1k.fs bsram-DPX9B18-tangnano1k.fs \ \ blinky-tangnano4k.fs shift-tangnano4k.fs blinky-tbuf-tangnano4k.fs blinky-oddr-tangnano4k.fs \ blinky-osc-tangnano4k.fs tlvds-tangnano4k.fs elvds-tangnano4k.fs oddr-tlvds-tangnano4k.fs \ @@ -41,6 +51,9 @@ all: \ oddr-elvds-tangnano9k.fs pll-nanolcd-tangnano9k.fs oser16-tangnano9k.fs attosoc-tangnano9k.fs \ oser4-tangnano9k.fs ovideo-tangnano9k.fs oser8-tangnano9k.fs oser10-tangnano9k.fs \ ides4-tangnano9k.fs ivideo-tangnano9k.fs ides8-tangnano9k.fs ides10-tangnano9k.fs \ + bsram-pROM-tangnano9k.fs bsram-SDPB-tangnano9k.fs bsram-SP-tangnano9k.fs \ + bsram-DPB-tangnano9k.fs bsram-pROMX9-tangnano9k.fs bsram-SDPX9B-tangnano9k.fs \ + bsram-SPX9-tangnano9k.fs bsram-DPX9B-tangnano9k.fs \ \ blinky-szfpga.fs shift-szfpga.fs blinky-tbuf-szfpga.fs blinky-oddr-szfpga.fs \ blinky-osc-szfpga.fs tlvds-szfpga.fs elvds-szfpga.fs oddr-tlvds-szfpga.fs \ @@ -48,6 +61,9 @@ all: \ oser4-szfpga.fs ovideo-szfpga.fs oser8-szfpga.fs oser10-szfpga.fs \ ides16-szfpga.fs \ ides4-szfpga.fs ivideo-szfpga.fs ides8-szfpga.fs ides10-szfpga.fs \ + bsram-pROM-szfpga.fs bsram-SDPB-szfpga.fs bsram-SP-szfpga.fs \ + bsram-pROMX9-szfpga.fs bsram-SDPX9B-szfpga.fs \ + bsram-SPX9-szfpga.fs \ \ blinky-tec0117.fs shift-tec0117.fs blinky-tbuf-tec0117.fs blinky-oddr-tec0117.fs \ blinky-osc-tec0117.fs tlvds-tec0117.fs elvds-tec0117.fs oddr-tlvds-tec0117.fs \ @@ -72,6 +88,10 @@ unpacked:\ oser8-tangnano20k-unpacked.v oser10-tangnano20k-unpacked.v \ ides4-tangnano20k-unpacked.v ivideo-tangnano20k-unpacked.v ides8-tangnano20k-unpacked.v \ ides10-tangnano20k-unpacked.v \ + bsram-pROM-tangnano20k-unpacked.v bsram-SDPB-tangnano20k-unpacked.v bsram-SP-tangnano20k-unpacked.v \ + bsram-DPB-tangnano20k-unpacked.v bsram-pROMX9-tangnano20k-unpacked.v \ + bsram-SDPX9B-tangnano20k-unpacked.v bsram-SPX9-tangnano-unpacked.v \ + bsram-DPX9B-tangnano20k-unpacked.v \ \ blinky-primer20k-unpacked.v shift-primer20k-unpacked.v blinky-tbuf-primer20k-unpacked.v \ blinky-oddr-primer20k-unpacked.v blinky-osc-primer20k-unpacked.v tlvds-primer20k-unpacked.v \ @@ -80,20 +100,30 @@ unpacked:\ oser4-primer20k-unpacked.v ovideo-primer20k-unpacked.v oser8-primer20k-unpacked.v \ oser10-primer20k-unpacked.v ides4-primer20k-unpacked.v ivideo-primer20k-unpacked.v \ ides8-primer20k-unpacked.v ides10-primer20k-unpacked.v \ + bsram-pROM-primer20k-unpacked.v bsram-SDPB-primer20k-unpacked.v bsram-SP-primer20k-unpacked.v \ + bsram-DPB-primer20k-unpacked.v bsram-pROMX9-primer20k-unpacked.v \ + bsram-SDPX9B-primer20k-unpacked.v bsram-SPX9-tangnano-unpacked.v \ + bsram-DPX9B-primer20k-unpacked.v \ \ blinky-tangnano-unpacked.v shift-tangnano-unpacked.v blinky-tbuf-tangnano-unpacked.v \ blinky-oddr-tangnano-unpacked.v blinky-osc-tangnano-unpacked.v elvds-tangnano-unpacked.v \ oddr-elvds-tangnano-unpacked.v pll-nanolcd-tangnano-unpacked.v \ oser4-tangnano-unpacked.v ovideo-tangnano-unpacked.v oser8-tangnano-unpacked.v \ oser10-tangnano-unpacked.v ides4-tangnano-unpacked.v ivideo-tangnano-unpacked.v \ - ides8-tangnano-unpacked.v ides10-tangnano-unpacked.v \ + ides8-tangnano-unpacked.v ides10-tangnano-unpacked.v bsram-pROM-tangnano-unpacked.v \ + bsram-SDPB-tangnano-unpacked.v bsram-SP-tangnano-unpacked.v bsram-pROMX9-tangnano-unpacked.v \ + bsram-SDPX9B-tangnano-unpacked.v bsram-SPX9-tangnano-unpacked.v \ + bsram-DPB-tangnano-unpacked.v bsram-DPX9B-tangnano-unpacked.v \ \ blinky-tangnano1k-unpacked.v shift-tangnano1k-unpacked.v blinky-tbuf-tangnano1k-unpacked.v \ blinky-oddr-tangnano1k-unpacked.v blinky-osc-tangnano1k-unpacked.v elvds-tangnano1k-unpacked.v \ oddr-elvds-tangnano1k-unpacked.v pll-nanolcd-tangnano1k-unpacked.v oser4-tangnano1k-unpacked.v \ ovideo-tangnano1k-unpacked.v oser8-tangnano1k-unpacked.v oser10-tangnano1k-unpacked.v \ ides4-tangnano1k-unpacked.v ivideo-tangnano1k-unpacked.v ides8-tangnano1k-unpacked.v \ - ides10-tangnano1k-unpacked.v \ + ides10-tangnano1k-unpacked.v bsram-pROM-tangnano1k-unpacked.v bsram-SDPB-tangnano1k-unpacked.v \ + bsram-DPB16-tangnano1k-unpacked.v bsram-SP-tangnano1k-unpacked.v \ + bsram-pROMX9-tangnano1k-unpacked.v bsram-SDPX9B-tangnano1k-unpacked.v \ + bsram-SPX9-tangnano1k-unpacked.v bsram-DPX9B18-tangnano1k-unpacked.v \ \ blinky-tangnano4k-unpacked.v shift-tangnano4k-unpacked.v blinky-tbuf-tangnano4k-unpacked.v \ blinky-oddr-tangnano4k-unpacked.v blinky-osc-tangnano4k-unpacked.v tlvds-tangnano4k-unpacked.v \ @@ -110,6 +140,10 @@ unpacked:\ oser4-tangnano9k-unpacked.v ovideo-tangnano9k-unpacked.v oser8-tangnano9k-unpacked.v \ oser10-tangnano9k-unpacked.v ides4-tangnano9k-unpacked.v ivideo-tangnano9k-unpacked.v \ ides8-tangnano9k-unpacked.v ides10-tangnano9k-unpacked.v \ + bsram-pROM-tangnano9k-unpacked.v bsram-SDPB-tangnano9k-unpacked.v bsram-SP-tangnano9k-unpacked.v \ + bsram-DPB-tangnano9k-unpacked.v bsram-pROMX9-tangnano9k-unpacked.v \ + bsram-SDPX9B-tangnano9k-unpacked.v bsram-SPX9-tangnano-unpacked.v \ + bsram-DPX9B-tangnano9k-unpacked.v \ \ blinky-szfpga-unpacked.v shift-szfpga-unpacked.v blinky-tbuf-szfpga-unpacked.v \ blinky-oddr-szfpga-unpacked.v blinky-osc-szfpga-unpacked.v tlvds-szfpga-unpacked.v \ @@ -118,6 +152,9 @@ unpacked:\ oser4-szfpga-unpacked.v ovideo-szfpga-unpacked.v oser8-szfpga-unpacked.v \ oser10-szfpga-unpacked.v ides16-szfpga-unpacked.v ides4-szfpga-unpacked.v \ ivideo-szfpga-unpacked.v ides8-szfpga-unpacked.v ides10-szfpga-unpacked.v \ + bsram-pROM-szfpga-unpacked.v bsram-SDPB-szfpga-unpacked.v bsram-SP-szfpga-unpacked.v \ + bsram-SDPX9B-szfpga-unpacked.v bsram-SPX9-tangnano-unpacked.v \ + bsram-pROMX9-szfpga-unpacked.v \ \ blinky-tec0117-unpacked.v shift-tec0117-unpacked.v blinky-tbuf-tec0117-unpacked.v \ blinky-oddr-tec0117-unpacked.v blinky-osc-tec0117-unpacked.v tlvds-tec0117-unpacked.v \ @@ -152,6 +189,9 @@ clean: pll-nanolcd-tangnano20k-synth.json: pll/GW2A-18-dyn.vh pll-nanolcd/TOP.v pll-nanolcd/VGAMod.v $(YOSYS) -D INV_BTN=1 -p "read_verilog $^; synth_gowin -json $@" +bsram-%-tangnano20k-synth.json: pll/GW2A-18-dyn.vh %-image-rom.v %-video-ram.v %.v + $(YOSYS) -D INV_BTN=1 -p "read_verilog $^; synth_gowin -json $@" + attosoc-tangnano20k-synth.json: attosoc/attosoc.v attosoc/picorv32.v $(YOSYS) -D INV_BTN=1 -p "read_verilog $^; synth_gowin -json $@" @@ -169,6 +209,9 @@ attosoc-tangnano20k-synth.json: attosoc/attosoc.v attosoc/picorv32.v pll-nanolcd-primer20k-synth.json: pll/GW2A-18-dyn.vh pll-nanolcd/TOP.v pll-nanolcd/VGAMod.v $(YOSYS) -D INV_BTN=0 -p "read_verilog $^; synth_gowin -json $@" +bsram-%-primer20k-synth.json: pll/GW2A-18-dyn.vh %-image-rom.v %-video-ram.v %.v + $(YOSYS) -D INV_BTN=0 -p "read_verilog $^; synth_gowin -json $@" + attosoc-%-synth.json: attosoc/attosoc.v attosoc/picorv32.v $(YOSYS) -D INV_BTN=0 -p "read_verilog $^; synth_gowin -json $@" @@ -186,6 +229,9 @@ attosoc-%-synth.json: attosoc/attosoc.v attosoc/picorv32.v pll-nanolcd-tangnano-synth.json: pll/GW1N-1-dyn.vh pll-nanolcd/TOP.v pll-nanolcd/VGAMod.v $(YOSYS) -D INV_BTN=0 -p "read_verilog $^; synth_gowin -noalu -json $@" +bsram-%-tangnano-synth.json: pll/GW1N-1-dyn.vh %-image-rom.v %-video-ram.v %.v + $(YOSYS) -D INV_BTN=0 -p "read_verilog $^; synth_gowin -json $@" + # ============================================================ # Tangnano1k (GW1NZ-1) %-tangnano1k.fs: %-tangnano1k.json @@ -203,6 +249,9 @@ pll-nanolcd-tangnano1k.fs: pll-nanolcd-tangnano1k.json pll-nanolcd-tangnano1k-synth.json: pll/GW1NZ-1-dyn.vh pll-nanolcd/TOP.v pll-nanolcd/VGAMod.v $(YOSYS) -D INV_BTN=0 -p "read_verilog $^; synth_gowin -noalu -json $@" +bsram-%-tangnano1k-synth.json: pll/GW1NZ-1-dyn.vh %-image-rom.v %-video-ram.v %.v + $(YOSYS) -D INV_BTN=0 -p "read_verilog $^; synth_gowin -json $@" + # ============================================================ # Tangnano4k (GW1NS-4) %-tangnano4k.fs: %-tangnano4k.json @@ -234,6 +283,9 @@ pll-nanolcd-tangnano9k-synth.json: pll/GW1N-9C-dyn.vh pll-nanolcd/TOP.v pll-nano pll-nanolcd-tangnano9k.fs: pll-nanolcd-tangnano9k.json gowin_pack -d GW1N-9C --sspi_as_gpio --mspi_as_gpio -o $@ $^ +bsram-%-tangnano9k-synth.json: pll/GW1N-9C-dyn.vh %-image-rom.v %-video-ram.v %.v + $(YOSYS) -D INV_BTN=0 -p "read_verilog $^; synth_gowin -json $@" + # ============================================================ # szfpga (GW1N-9) %-szfpga.fs: %-szfpga.json @@ -248,6 +300,9 @@ pll-nanolcd-tangnano9k.fs: pll-nanolcd-tangnano9k.json blinky-pll-szfpga-synth.json: pll/GW1N-9-dyn.vh blinky-pll.v $(YOSYS) -D INV_BTN=0 -D LEDS_NR=4 -p "read_verilog $^; synth_gowin -json $@" +bsram-%-szfpga-synth.json: pll/GW1N-9-dyn.vh %-image-rom.v %-video-ram.v %.v + $(YOSYS) -D INV_BTN=0 -p "read_verilog $^; synth_gowin -json $@" + # ============================================================ # tec0117 (GW1N-9) %-tec0117.fs: %-tec0117.json diff --git a/examples/himbaechel/SDPB-image-rom.v b/examples/himbaechel/SDPB-image-rom.v new file mode 120000 index 00000000..907c49ad --- /dev/null +++ b/examples/himbaechel/SDPB-image-rom.v @@ -0,0 +1 @@ +pROM-image-rom.v \ No newline at end of file diff --git a/examples/himbaechel/SDPB-video-ram.v b/examples/himbaechel/SDPB-video-ram.v new file mode 100644 index 00000000..d4f57d4c --- /dev/null +++ b/examples/himbaechel/SDPB-video-ram.v @@ -0,0 +1,43 @@ +`default_nettype none +module video_ram( + input wire clk, + input wire reset, + input wire write_clk, + input wire write_reset, + input wire write_ce, + input wire [10:0] write_ad, + input wire [7:0] write_data, + input wire [10:0] read_ad, + output wire [7:0] read_data +); + + wire gnd, vcc; + assign gnd = 1'b0; + assign vcc = 1'b1; + + wire [23:0] dummy_w; + + SDPB mem( + .DO({dummy_w, read_data}), + .DI({{24{gnd}}, write_data}), + .ADA({write_ad, gnd, gnd, gnd}), + .ADB({ read_ad, gnd, gnd, gnd}), + .CLKA(write_clk), + .CLKB(clk), + .OCE(vcc), + .CEA(write_ce), + .CEB(vcc), + .BLKSELA(3'b000), + .BLKSELB(3'b000), + .RESETA(write_reset), + .RESETB(reset) + ); + defparam mem.READ_MODE = 1'b1; + defparam mem.BIT_WIDTH_0 = 8; + defparam mem.BIT_WIDTH_1 = 8; + defparam mem.BLK_SEL_0 = 3'b000; + defparam mem.BLK_SEL_1 = 3'b000; + defparam mem.RESET_MODE = "SYNC"; +`include "img-video-ram.vh" +endmodule + diff --git a/examples/himbaechel/SDPB.v b/examples/himbaechel/SDPB.v new file mode 100644 index 00000000..235ad120 --- /dev/null +++ b/examples/himbaechel/SDPB.v @@ -0,0 +1,174 @@ +`default_nettype none +(* top *) +module top +( + input wire rst_i, + input wire clk, + + output wire LCD_CLK, + output wire LCD_HYNC, + output wire LCD_SYNC, + output wire LCD_DEN, + output wire [4:0] LCD_R, + output wire [5:0] LCD_G, + output wire [4:0] LCD_B +); + + wire rst = rst_i ^ `INV_BTN; + wire pixel_clk; + wire write_clk; + + wire gnd; + assign gnd = 1'b0; + + rPLL pll( + .CLKOUT(pixel_clk), // 9MHz + .CLKOUTD(write_clk), + .CLKIN(clk), + .CLKFB(gnd), + .RESET(!rst), + .RESET_P(!rst), + .FBDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .IDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .ODSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .DUTYDA({gnd, gnd, gnd, gnd}), + .PSDA({gnd, gnd, gnd, gnd}), + .FDLY({gnd, gnd, gnd, gnd}) + ); + defparam pll.DEVICE = `PLL_DEVICE; + defparam pll.FCLKIN = `PLL_FCLKIN; + defparam pll.FBDIV_SEL = `PLL_FBDIV_SEL_LCD; + defparam pll.IDIV_SEL = `PLL_IDIV_SEL_LCD; + defparam pll.ODIV_SEL = `PLL_ODIV_SEL; + defparam pll.CLKFB_SEL="internal"; + defparam pll.CLKOUTD3_SRC="CLKOUT"; + defparam pll.CLKOUTD_BYPASS="false"; + defparam pll.CLKOUTD_SRC="CLKOUT"; + defparam pll.CLKOUTP_BYPASS="false"; + defparam pll.CLKOUTP_DLY_STEP=0; + defparam pll.CLKOUTP_FT_DIR=1'b1; + defparam pll.CLKOUT_BYPASS="false"; + defparam pll.CLKOUT_DLY_STEP=0; + defparam pll.CLKOUT_FT_DIR=1'b1; + defparam pll.DUTYDA_SEL="1000"; + defparam pll.DYN_DA_EN="false"; + defparam pll.DYN_FBDIV_SEL="false"; + defparam pll.DYN_IDIV_SEL="false"; + defparam pll.DYN_ODIV_SEL="false"; + defparam pll.DYN_SDIV_SEL=128; + defparam pll.PSDA_SEL="0000"; + + assign LCD_CLK = pixel_clk; + + reg [15:0] pixel_count; + reg [15:0] line_count; + + + /* 480x272 4.3" LCD with SC7283 driver, pixel freq = 9MHz */ + localparam VBackPorch = 16'd12; + localparam VPulse = 16'd4; + localparam HightPixel = 16'd272; + localparam VFrontPorch= 16'd8; + + localparam HBackPorch = 16'd43; + localparam HPulse = 16'd4; + localparam WidthPixel = 16'd480; + localparam HFrontPorch= 16'd8; + + + localparam PixelForHS = WidthPixel + HBackPorch + HFrontPorch; + localparam LineForVS = HightPixel + VBackPorch + VFrontPorch; + + always @(posedge pixel_clk or negedge rst)begin + if (!rst) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else if (pixel_count == PixelForHS) begin + pixel_count <= 16'b0; + line_count <= line_count + 1'b1; + end + else if (line_count == LineForVS) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else begin + pixel_count <= pixel_count + 1'b1; + end + end + + + assign LCD_HYNC = ((pixel_count >= HPulse) && (pixel_count <= (PixelForHS - HFrontPorch))) ? 1'b0 : 1'b1; + assign LCD_SYNC = (((line_count >= VPulse) && (line_count <= (LineForVS - 0)))) ? 1'b0 : 1'b1; + + assign LCD_DEN = ((pixel_count >= HBackPorch)&& + (pixel_count <= PixelForHS - HFrontPorch) && + (line_count >= VBackPorch) && + (line_count <= LineForVS - VFrontPorch - 1)) ? 1'b1 : 1'b0; + + wire [7:0] rom_data_w; + reg [10:0] read_addr; + reg [16:0] write_addr; + reg write_ce; + + image_rom image( + .clk(pixel_clk), + .reset(!rst), + .ad(write_addr[16:5]), + .data(rom_data_w) + ); + + wire [7:0] dout; + video_ram vmem( + .clk(pixel_clk), + .write_clk(write_clk), + .reset(!rst), + .write_reset(!rst), + .write_ce(write_ce), + .read_ad(read_addr), + .read_data(dout), + .write_ad(write_addr[15:5]), + .write_data(rom_data_w) + ); + + always @(posedge write_clk or negedge rst) begin + if (!rst) begin + write_ce <= 1; + write_addr <= 0; + end else begin + write_addr <= write_addr + 1; + end + end + +`define START_X 16'd160 +`define STOP_X (`START_X + 16'd256) +`define START_Y 16'd18 +`define STOP_Y (`START_Y + 16'd256) + + wire [7:0] vmem_start_col; + wire [7:0] vmem_start_row; + assign vmem_start_col = pixel_count - `START_X; + assign vmem_start_row = line_count - `START_Y; + + always @(negedge pixel_clk) begin + read_addr = {vmem_start_row[7:2], vmem_start_col[7:2]}; + end + + wire is_out_x = pixel_count < `START_X || pixel_count >= `STOP_X; + wire is_out_y = line_count < `START_Y || line_count >= `STOP_Y; + + reg [15:0] color; + always @(posedge pixel_clk) begin + if (is_out_x || is_out_y) begin + color = line_count + pixel_count; + end else begin + color = {dout[4:0], dout[5:0], dout[4:0]}; + end + end + + assign LCD_R = color[4:0]; + assign LCD_G = color[10:5]; + assign LCD_B = color[15:11]; + +endmodule + diff --git a/examples/himbaechel/SDPX9B-image-rom.v b/examples/himbaechel/SDPX9B-image-rom.v new file mode 120000 index 00000000..32b94c73 --- /dev/null +++ b/examples/himbaechel/SDPX9B-image-rom.v @@ -0,0 +1 @@ +pROMX9-image-rom.v \ No newline at end of file diff --git a/examples/himbaechel/SDPX9B-video-ram.v b/examples/himbaechel/SDPX9B-video-ram.v new file mode 100644 index 00000000..c33b526e --- /dev/null +++ b/examples/himbaechel/SDPX9B-video-ram.v @@ -0,0 +1,43 @@ +`default_nettype none +module video_ram( + input wire clk, + input wire reset, + input wire write_clk, + input wire write_reset, + input wire write_ce, + input wire [10:0] write_ad, + input wire [8:0] write_data, + input wire [10:0] read_ad, + output wire [8:0] read_data +); + + wire gnd, vcc; + assign gnd = 1'b0; + assign vcc = 1'b1; + + wire [26:0] dummy_w; + + SDPX9B mem( + .DO({dummy_w, read_data}), + .DI({{27{gnd}}, write_data}), + .ADA({write_ad, gnd, gnd, gnd}), + .ADB({ read_ad, gnd, gnd, gnd}), + .CLKA(write_clk), + .CLKB(clk), + .OCE(vcc), + .CEA(write_ce), + .CEB(vcc), + .BLKSELA(3'b000), + .BLKSELB(3'b000), + .RESETA(write_reset), + .RESETB(reset) + ); + defparam mem.READ_MODE = 1'b1; + defparam mem.BIT_WIDTH_0 = 9; + defparam mem.BIT_WIDTH_1 = 9; + defparam mem.BLK_SEL_0 = 3'b000; + defparam mem.BLK_SEL_1 = 3'b000; + defparam mem.RESET_MODE = "SYNC"; +`include "img-video-ram1.vh" +endmodule + diff --git a/examples/himbaechel/SDPX9B.v b/examples/himbaechel/SDPX9B.v new file mode 100644 index 00000000..8a17dda9 --- /dev/null +++ b/examples/himbaechel/SDPX9B.v @@ -0,0 +1,174 @@ +`default_nettype none +(* top *) +module top +( + input wire rst_i, + input wire clk, + + output wire LCD_CLK, + output wire LCD_HYNC, + output wire LCD_SYNC, + output wire LCD_DEN, + output wire [4:0] LCD_R, + output wire [5:0] LCD_G, + output wire [4:0] LCD_B +); + + wire rst = rst_i ^ `INV_BTN; + wire pixel_clk; + wire write_clk; + + wire gnd; + assign gnd = 1'b0; + + rPLL pll( + .CLKOUT(pixel_clk), // 9MHz + .CLKOUTD(write_clk), + .CLKIN(clk), + .CLKFB(gnd), + .RESET(!rst), + .RESET_P(!rst), + .FBDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .IDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .ODSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .DUTYDA({gnd, gnd, gnd, gnd}), + .PSDA({gnd, gnd, gnd, gnd}), + .FDLY({gnd, gnd, gnd, gnd}) + ); + defparam pll.DEVICE = `PLL_DEVICE; + defparam pll.FCLKIN = `PLL_FCLKIN; + defparam pll.FBDIV_SEL = `PLL_FBDIV_SEL_LCD; + defparam pll.IDIV_SEL = `PLL_IDIV_SEL_LCD; + defparam pll.ODIV_SEL = `PLL_ODIV_SEL; + defparam pll.CLKFB_SEL="internal"; + defparam pll.CLKOUTD3_SRC="CLKOUT"; + defparam pll.CLKOUTD_BYPASS="false"; + defparam pll.CLKOUTD_SRC="CLKOUT"; + defparam pll.CLKOUTP_BYPASS="false"; + defparam pll.CLKOUTP_DLY_STEP=0; + defparam pll.CLKOUTP_FT_DIR=1'b1; + defparam pll.CLKOUT_BYPASS="false"; + defparam pll.CLKOUT_DLY_STEP=0; + defparam pll.CLKOUT_FT_DIR=1'b1; + defparam pll.DUTYDA_SEL="1000"; + defparam pll.DYN_DA_EN="false"; + defparam pll.DYN_FBDIV_SEL="false"; + defparam pll.DYN_IDIV_SEL="false"; + defparam pll.DYN_ODIV_SEL="false"; + defparam pll.DYN_SDIV_SEL=128; + defparam pll.PSDA_SEL="0000"; + + assign LCD_CLK = pixel_clk; + + reg [15:0] pixel_count; + reg [15:0] line_count; + + + /* 480x272 4.3" LCD with SC7283 driver, pixel freq = 9MHz */ + localparam VBackPorch = 16'd12; + localparam VPulse = 16'd4; + localparam HightPixel = 16'd272; + localparam VFrontPorch= 16'd8; + + localparam HBackPorch = 16'd43; + localparam HPulse = 16'd4; + localparam WidthPixel = 16'd480; + localparam HFrontPorch= 16'd8; + + + localparam PixelForHS = WidthPixel + HBackPorch + HFrontPorch; + localparam LineForVS = HightPixel + VBackPorch + VFrontPorch; + + always @(posedge pixel_clk or negedge rst)begin + if (!rst) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else if (pixel_count == PixelForHS) begin + pixel_count <= 16'b0; + line_count <= line_count + 1'b1; + end + else if (line_count == LineForVS) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else begin + pixel_count <= pixel_count + 1'b1; + end + end + + + assign LCD_HYNC = ((pixel_count >= HPulse) && (pixel_count <= (PixelForHS - HFrontPorch))) ? 1'b0 : 1'b1; + assign LCD_SYNC = (((line_count >= VPulse) && (line_count <= (LineForVS - 0)))) ? 1'b0 : 1'b1; + + assign LCD_DEN = ((pixel_count >= HBackPorch)&& + (pixel_count <= PixelForHS - HFrontPorch) && + (line_count >= VBackPorch) && + (line_count <= LineForVS - VFrontPorch - 1)) ? 1'b1 : 1'b0; + + wire [8:0] rom_data_w; + reg [10:0] read_addr; + reg [16:0] write_addr; + reg write_ce; + + image_rom image( + .clk(pixel_clk), + .reset(!rst), + .ad(write_addr[16:5]), + .data(rom_data_w) + ); + + wire [8:0] dout; + video_ram vmem( + .clk(pixel_clk), + .write_clk(write_clk), + .reset(!rst), + .write_reset(!rst), + .write_ce(write_ce), + .read_ad(read_addr), + .read_data(dout), + .write_ad(write_addr[15:5]), + .write_data(rom_data_w) + ); + + always @(posedge write_clk or negedge rst) begin + if (!rst) begin + write_ce <= 1; + write_addr <= 0; + end else begin + write_addr <= write_addr + 1; + end + end + +`define START_X 16'd160 +`define STOP_X (`START_X + 16'd256) +`define START_Y 16'd18 +`define STOP_Y (`START_Y + 16'd256) + + wire [7:0] vmem_start_col; + wire [7:0] vmem_start_row; + assign vmem_start_col = pixel_count - `START_X; + assign vmem_start_row = line_count - `START_Y; + + always @(negedge pixel_clk) begin + read_addr = {vmem_start_row[7:2], vmem_start_col[7:2]}; + end + + wire is_out_x = pixel_count < `START_X || pixel_count >= `STOP_X; + wire is_out_y = line_count < `START_Y || line_count >= `STOP_Y; + + reg [15:0] color; + always @(posedge pixel_clk) begin + if (is_out_x || is_out_y) begin + color = line_count + pixel_count; + end else begin + color = {dout[8:4], dout[8:3], dout[8:4]}; + end + end + + assign LCD_R = color[4:0]; + assign LCD_G = color[10:5]; + assign LCD_B = color[15:11]; + +endmodule + diff --git a/examples/himbaechel/SP-image-rom.v b/examples/himbaechel/SP-image-rom.v new file mode 120000 index 00000000..907c49ad --- /dev/null +++ b/examples/himbaechel/SP-image-rom.v @@ -0,0 +1 @@ +pROM-image-rom.v \ No newline at end of file diff --git a/examples/himbaechel/SP-video-ram.v b/examples/himbaechel/SP-video-ram.v new file mode 100644 index 00000000..661620f1 --- /dev/null +++ b/examples/himbaechel/SP-video-ram.v @@ -0,0 +1,35 @@ +`default_nettype none +module video_ram( + input wire clk, + input wire reset, + input wire wre, + input wire [7:0] write_data, + input wire [10:0] ad, + output wire [7:0] read_data +); + + wire gnd, vcc; + assign gnd = 1'b0; + assign vcc = 1'b1; + + wire [23:0] dummy; + + SP mem( + .DO({dummy, read_data}), + .DI({{24{gnd}}, write_data}), + .AD({ad, gnd, gnd, gnd}), + .CLK(clk), + .CE(vcc), + .WRE(wre), + .OCE(vcc), + .BLKSEL(3'b000), + .RESET(reset) + ); + defparam mem.READ_MODE = 1'b1; + defparam mem.WRITE_MODE = 2'b01; + defparam mem.BIT_WIDTH = 8; + defparam mem.BLK_SEL = 3'b000; + defparam mem.RESET_MODE = "SYNC"; +`include "img-video-ram.vh" +endmodule + diff --git a/examples/himbaechel/SP.v b/examples/himbaechel/SP.v new file mode 100644 index 00000000..cfbf2a1a --- /dev/null +++ b/examples/himbaechel/SP.v @@ -0,0 +1,182 @@ +`default_nettype none +(* top *) +module top +( + input wire rst_i, + input wire clk, + + output wire LCD_CLK, + output wire LCD_HYNC, + output wire LCD_SYNC, + output wire LCD_DEN, + output wire [4:0] LCD_R, + output wire [5:0] LCD_G, + output wire [4:0] LCD_B +); + + wire rst = rst_i ^ `INV_BTN; + wire pixel_clk; + wire write_clk; + + wire gnd; + assign gnd = 1'b0; + + rPLL pll( + .CLKOUT(pixel_clk), // 9MHz + .CLKOUTD(write_clk), + .CLKIN(clk), + .CLKFB(gnd), + .RESET(!rst), + .RESET_P(!rst), + .FBDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .IDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .ODSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .DUTYDA({gnd, gnd, gnd, gnd}), + .PSDA({gnd, gnd, gnd, gnd}), + .FDLY({gnd, gnd, gnd, gnd}) + ); + defparam pll.DEVICE = `PLL_DEVICE; + defparam pll.FCLKIN = `PLL_FCLKIN; + defparam pll.FBDIV_SEL = `PLL_FBDIV_SEL_LCD; + defparam pll.IDIV_SEL = `PLL_IDIV_SEL_LCD; + defparam pll.ODIV_SEL = `PLL_ODIV_SEL; + defparam pll.CLKFB_SEL="internal"; + defparam pll.CLKOUTD3_SRC="CLKOUT"; + defparam pll.CLKOUTD_BYPASS="false"; + defparam pll.CLKOUTD_SRC="CLKOUT"; + defparam pll.CLKOUTP_BYPASS="false"; + defparam pll.CLKOUTP_DLY_STEP=0; + defparam pll.CLKOUTP_FT_DIR=1'b1; + defparam pll.CLKOUT_BYPASS="false"; + defparam pll.CLKOUT_DLY_STEP=0; + defparam pll.CLKOUT_FT_DIR=1'b1; + defparam pll.DUTYDA_SEL="1000"; + defparam pll.DYN_DA_EN="false"; + defparam pll.DYN_FBDIV_SEL="false"; + defparam pll.DYN_IDIV_SEL="false"; + defparam pll.DYN_ODIV_SEL="false"; + defparam pll.DYN_SDIV_SEL=128; + defparam pll.PSDA_SEL="0000"; + + assign LCD_CLK = pixel_clk; + + reg [15:0] pixel_count; + reg [15:0] line_count; + + /* 480x272 4.3" LCD with SC7283 driver, pixel freq = 9MHz */ + localparam VBackPorch = 16'd12; + localparam VPulse = 16'd4; + localparam HightPixel = 16'd272; + localparam VFrontPorch= 16'd8; + + localparam HBackPorch = 16'd43; + localparam HPulse = 16'd4; + localparam WidthPixel = 16'd480; + localparam HFrontPorch= 16'd8; + + + localparam PixelForHS = WidthPixel + HBackPorch + HFrontPorch; + localparam LineForVS = HightPixel + VBackPorch + VFrontPorch; + + always @(posedge pixel_clk or negedge rst)begin + if (!rst) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else if (pixel_count == PixelForHS) begin + pixel_count <= 16'b0; + line_count <= line_count + 1'b1; + end + else if (line_count == LineForVS) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else begin + pixel_count <= pixel_count + 1'b1; + end + end + + + assign LCD_HYNC = ((pixel_count >= HPulse) && (pixel_count <= (PixelForHS - HFrontPorch))) ? 1'b0 : 1'b1; + assign LCD_SYNC = (((line_count >= VPulse) && (line_count <= (LineForVS - 0)))) ? 1'b0 : 1'b1; + + assign LCD_DEN = ((pixel_count >= HBackPorch)&& + (pixel_count <= PixelForHS - HFrontPorch) && + (line_count >= VBackPorch) && + (line_count <= LineForVS - VFrontPorch - 1)) ? 1'b1 : 1'b0; + + wire [7:0] rom_data; + reg [10:0] read_addr; + reg [16:0] write_addr; + + image_rom image( + .clk(pixel_clk), + .reset(!rst), + .ad(write_addr[16:5]), + .data(rom_data) + ); + + wire [7:0] dout; + wire [10:0] rw_addr; + + video_ram vmem( + .clk(pixel_clk), + .reset(!rst), + .wre(!LCD_DEN), + .ad(rw_addr), + .read_data(dout), + .write_data(rom_data) + ); + + +`define START_X 16'd160 +`define STOP_X (`START_X + 16'd256) +`define START_Y 16'd18 +`define STOP_Y (`START_Y + 16'd256) + + wire [7:0] vmem_start_col; + wire [7:0] vmem_start_row; + assign vmem_start_col = pixel_count - `START_X; + assign vmem_start_row = line_count - `START_Y; + + always @(negedge pixel_clk) begin + read_addr = {vmem_start_row[7:2], vmem_start_col[7:2]}; + end + + wire is_out_x = pixel_count < `START_X || pixel_count >= `STOP_X; + wire is_out_y = line_count < `START_Y || line_count >= `STOP_Y; + + /* + always @(negedge pixel_clk) begin + if (is_out_x) begin + rw_addr <= write_addr[15:5]; + end else begin + rw_addr <= read_addr; + end + end + */ + assign rw_addr = is_out_x ? write_addr[15:5] : read_addr; + + reg [15:0] color; + always @(posedge pixel_clk) begin + if (is_out_x || is_out_y) begin + color = line_count + pixel_count; + end else begin + color = {dout[4:0], dout[5:0], dout[4:0]}; + end + end + + always @(posedge write_clk or negedge rst) begin + if (!rst) begin + write_addr <= 0; + end else begin + write_addr <= write_addr + 1; + end + end + + assign LCD_R = color[4:0]; + assign LCD_G = color[10:5]; + assign LCD_B = color[15:11]; + +endmodule + diff --git a/examples/himbaechel/SPX9-image-rom.v b/examples/himbaechel/SPX9-image-rom.v new file mode 120000 index 00000000..32b94c73 --- /dev/null +++ b/examples/himbaechel/SPX9-image-rom.v @@ -0,0 +1 @@ +pROMX9-image-rom.v \ No newline at end of file diff --git a/examples/himbaechel/SPX9-video-ram.v b/examples/himbaechel/SPX9-video-ram.v new file mode 100644 index 00000000..13341c98 --- /dev/null +++ b/examples/himbaechel/SPX9-video-ram.v @@ -0,0 +1,35 @@ +`default_nettype none +module video_ram( + input wire clk, + input wire reset, + input wire wre, + input wire [8:0] write_data, + input wire [10:0] ad, + output wire [8:0] read_data +); + + wire gnd, vcc; + assign gnd = 1'b0; + assign vcc = 1'b1; + + wire [26:0] dummy; + + SPX9 mem( + .DO({dummy, read_data}), + .DI({{27{gnd}}, write_data}), + .AD({ad, gnd, gnd, gnd}), + .CLK(clk), + .CE(vcc), + .WRE(wre), + .OCE(vcc), + .BLKSEL(3'b000), + .RESET(reset) + ); + defparam mem.READ_MODE = 1'b1; + defparam mem.WRITE_MODE = 2'b01; + defparam mem.BIT_WIDTH = 9; + defparam mem.BLK_SEL = 3'b000; + defparam mem.RESET_MODE = "SYNC"; +`include "img-video-ram1.vh" +endmodule + diff --git a/examples/himbaechel/SPX9.v b/examples/himbaechel/SPX9.v new file mode 100644 index 00000000..61143026 --- /dev/null +++ b/examples/himbaechel/SPX9.v @@ -0,0 +1,177 @@ +`default_nettype none +(* top *) +module top +( + input wire rst_i, + input wire clk, + + output wire LCD_CLK, + output wire LCD_HYNC, + output wire LCD_SYNC, + output wire LCD_DEN, + output wire [4:0] LCD_R, + output wire [5:0] LCD_G, + output wire [4:0] LCD_B +); + + wire rst = rst_i ^ `INV_BTN; + wire pixel_clk; + wire write_clk; + + wire gnd; + assign gnd = 1'b0; + + rPLL pll( + .CLKOUT(pixel_clk), // 9MHz + .CLKOUTD(write_clk), + .CLKIN(clk), + .CLKFB(gnd), + .RESET(gnd), + .RESET_P(gnd), + .FBDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .IDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .ODSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .DUTYDA({gnd, gnd, gnd, gnd}), + .PSDA({gnd, gnd, gnd, gnd}), + .FDLY({gnd, gnd, gnd, gnd}) + ); + defparam pll.DEVICE = `PLL_DEVICE; + defparam pll.FCLKIN = `PLL_FCLKIN; + defparam pll.FBDIV_SEL = `PLL_FBDIV_SEL_LCD; + defparam pll.IDIV_SEL = `PLL_IDIV_SEL_LCD; + defparam pll.ODIV_SEL = `PLL_ODIV_SEL; + defparam pll.CLKFB_SEL="internal"; + defparam pll.CLKOUTD3_SRC="CLKOUT"; + defparam pll.CLKOUTD_BYPASS="false"; + defparam pll.CLKOUTD_SRC="CLKOUT"; + defparam pll.CLKOUTP_BYPASS="false"; + defparam pll.CLKOUTP_DLY_STEP=0; + defparam pll.CLKOUTP_FT_DIR=1'b1; + defparam pll.CLKOUT_BYPASS="false"; + defparam pll.CLKOUT_DLY_STEP=0; + defparam pll.CLKOUT_FT_DIR=1'b1; + defparam pll.DUTYDA_SEL="1000"; + defparam pll.DYN_DA_EN="false"; + defparam pll.DYN_FBDIV_SEL="false"; + defparam pll.DYN_IDIV_SEL="false"; + defparam pll.DYN_ODIV_SEL="false"; + defparam pll.DYN_SDIV_SEL=128; + defparam pll.PSDA_SEL="0000"; + + assign LCD_CLK = pixel_clk; + + reg [15:0] pixel_count; + reg [15:0] line_count; + + /* 480x272 4.3" LCD with SC7283 driver, pixel freq = 9MHz */ + localparam VBackPorch = 16'd12; + localparam VPulse = 16'd4; + localparam HightPixel = 16'd272; + localparam VFrontPorch= 16'd8; + + localparam HBackPorch = 16'd43; + localparam HPulse = 16'd4; + localparam WidthPixel = 16'd480; + localparam HFrontPorch= 16'd8; + + + localparam PixelForHS = WidthPixel + HBackPorch + HFrontPorch; + localparam LineForVS = HightPixel + VBackPorch + VFrontPorch; + + always @(posedge pixel_clk or negedge rst)begin + if (!rst) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else if (pixel_count == PixelForHS) begin + pixel_count <= 16'b0; + line_count <= line_count + 1'b1; + end + else if (line_count == LineForVS) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else begin + pixel_count <= pixel_count + 1'b1; + end + end + + + assign LCD_HYNC = ((pixel_count >= HPulse) && (pixel_count <= (PixelForHS - HFrontPorch))) ? 1'b0 : 1'b1; + assign LCD_SYNC = (((line_count >= VPulse) && (line_count <= (LineForVS - 0)))) ? 1'b0 : 1'b1; + + assign LCD_DEN = ((pixel_count >= HBackPorch)&& + (pixel_count <= PixelForHS - HFrontPorch) && + (line_count >= VBackPorch) && + (line_count <= LineForVS - VFrontPorch - 1)) ? 1'b1 : 1'b0; + + wire [8:0] rom_data; + wire [10:0] read_addr; + reg [16:0] write_addr; + + image_rom image( + .clk(pixel_clk), + .reset(!rst), + .ad(write_addr[16:5]), + .data(rom_data) + ); + + wire [8:0] dout; + reg [10:0] rw_addr; + + video_ram vmem( + .clk(pixel_clk), + .reset(!rst), + .wre(!LCD_DEN), + .ad(rw_addr), + .read_data(dout), + .write_data(rom_data) + ); + + +`define START_X 16'd160 +`define STOP_X (`START_X + 16'd256) +`define START_Y 16'd18 +`define STOP_Y (`START_Y + 16'd256) + + wire [7:0] vmem_start_col; + wire [7:0] vmem_start_row; + assign vmem_start_col = pixel_count - `START_X; + assign vmem_start_row = line_count - `START_Y; + + assign read_addr = {vmem_start_row[7:2], vmem_start_col[7:2]}; + + wire is_out_x = pixel_count < `START_X || pixel_count >= `STOP_X; + wire is_out_y = line_count < `START_Y || line_count >= `STOP_Y; + + always @(negedge pixel_clk) begin + if (is_out_x) begin + rw_addr <= write_addr[15:5]; + end else begin + rw_addr <= read_addr; + end + end + + reg [15:0] color; + always @(posedge pixel_clk) begin + if (is_out_x || is_out_y) begin + color = line_count + pixel_count; + end else begin + color = {dout[8:4], dout[8:3], dout[8:4]}; + end + end + + always @(posedge write_clk or negedge rst) begin + if (!rst) begin + write_addr <= 0; + end else begin + write_addr <= write_addr + 1; + end + end + + assign LCD_R = color[4:0]; + assign LCD_G = color[10:5]; + assign LCD_B = color[15:11]; + +endmodule + diff --git a/examples/himbaechel/img-rom.vh b/examples/himbaechel/img-rom.vh new file mode 100644 index 00000000..531aa995 --- /dev/null +++ b/examples/himbaechel/img-rom.vh @@ -0,0 +1,67 @@ +`ifndef _img_vh_ +`define _img_vh_ + defparam rom.INIT_RAM_00 = 256'h0F0F0F0F0F0F101010101010100F101010101010101010100F0F0F1010101010; + defparam rom.INIT_RAM_01 = 256'h0909090A0A0B0C0C0D0D0E0E0E0E0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F100F; + defparam rom.INIT_RAM_02 = 256'h0F0F0F0D000E1010101010101010101010101010101010100F0F0F1010101010; + defparam rom.INIT_RAM_03 = 256'h0909090A0A0B0C0C0D0D0D0E0E0E0F0F0F0F0F0F0F0F0F0F0B03000000040C0F; + defparam rom.INIT_RAM_04 = 256'h0D0F0D0100020E10101010101010101010101010101010100F0F0F1010101010; + defparam rom.INIT_RAM_05 = 256'h0909090A0A0B0C0C0D0D0D0D0D0E0F0F0F0F0F0F0F100E040000000000000003; + defparam rom.INIT_RAM_06 = 256'h010F01000000020E10100F0F0F0F10101010101010101010100F0F1010101010; + defparam rom.INIT_RAM_07 = 256'h090909090A0B0C0C0D0D0D0D0D0E0E0F0F0F0F0F0F0E01000000000000000000; + defparam rom.INIT_RAM_08 = 256'h000000031F0300020E0F0F0F0F0F0F0F0F101010101010101010101010101010; + defparam rom.INIT_RAM_09 = 256'h090909090A05000000010B0D0D0D0E0E0E0E0E0E0D0100010C0C1F1F1F170700; + defparam rom.INIT_RAM_0A = 256'h0300031B1F1B0300010D0F0F0F0F0F0F0F0F1010101010101010101010101010; + defparam rom.INIT_RAM_0B = 256'h08090909090000000000010A0D0D0D0D0E0E0E0A0100010A0C0C1F1F1F1F1F17; + defparam rom.INIT_RAM_0C = 256'h1B001B1F1F1F1B0300010D0F0F0F0F0F0F101010101010101010101010101010; + defparam rom.INIT_RAM_0D = 256'h090909090900000000000000030A0D0D0E0A030000010A0C0E1D1F1F1F1F1F1F; + defparam rom.INIT_RAM_0E = 256'h1F1F1F1F1F1F1F17000003101010101010101010101010101010101010101010; + defparam rom.INIT_RAM_0F = 256'h0909090909000000080F02000000000000000000010A0C0C1A1F1F1F1F1F1F1F; + defparam rom.INIT_RAM_10 = 256'h1F1F1F1F1F1F1F1F0700000C1010101010101010101010101010101010101010; + defparam rom.INIT_RAM_11 = 256'h09090908080100000F110F0000000000000000030A0C0C111F1F1F1F1F1F1F1F; + defparam rom.INIT_RAM_12 = 256'h1F1F1F1F1F1F1F1F170000041010101010101010101010101010101010101010; + defparam rom.INIT_RAM_13 = 256'h0909090908070100020F11080000000000040C0E0D0C0C1A1F1F1F1F1F1F1F1F; + defparam rom.INIT_RAM_14 = 256'h0F000F1F1F1F1F1F1F0000000B0F0F0F0F101010101010101010101010101010; + defparam rom.INIT_RAM_15 = 256'h090909090908070100000811111111111111110F0D0C0C1F1F1F0F000F1F1F1F; + defparam rom.INIT_RAM_16 = 256'h0000001F1F1F1F1F1F000000030F0F0F0F0F1010101010101010101010101010; + defparam rom.INIT_RAM_17 = 256'h08090909090908070100000F111111111111110F0D0C0C1F1F1F0000001F1F1F; + defparam rom.INIT_RAM_18 = 256'h0F000F1F1F1F1F1F1F000000000B0F0F0F101010101010101010101010101010; + defparam rom.INIT_RAM_19 = 256'h0909090909090908070100020F0F0F0F0F11110F0D0C0C1F1F1F0F000F1F1F1F; + defparam rom.INIT_RAM_1A = 256'h1F1F1F1F1F1F1F1F1A0C0C0100010D1010101010101010101010101010101010; + defparam rom.INIT_RAM_1B = 256'h090909090909090908070100020C0D0D0E0F110F0D0C0C1A1F1F1F1F1F1F1F1F; + defparam rom.INIT_RAM_1C = 256'h1F1F1F1F1F1F1F1F110C0C0A0100010E10101010101010101010101010101010; + defparam rom.INIT_RAM_1D = 256'h09090908090909090908070100010A0C0D0F110F0D0C0C111F1F1F1F1F1F1F1F; + defparam rom.INIT_RAM_1E = 256'h1F1F1F1F1F1F1F1A0C0C0D0D0C0200010E101010101010101010101010101010; + defparam rom.INIT_RAM_1F = 256'h0909090909090909090909070100010A0C0E0F0E0E0D0C0C1A1F1F1F1F1F1F1F; + defparam rom.INIT_RAM_20 = 256'h1D0C1D1F1F1F1D0E0C0E0F0F0F0F0200010E1010101010101010101010101010; + defparam rom.INIT_RAM_21 = 256'h090909090909090909090909080100010A0C0D0E0E0F0E0C0E1D1F1F1F1F1F1F; + defparam rom.INIT_RAM_22 = 256'h0E0C0E1D1F1D0E0C0D0F111111110F0200020E10101010101010101010101010; + defparam rom.INIT_RAM_23 = 256'h08090909090909090909090909080100010A0C0D0F110F0D0C0E1A1F1F1F1F1A; + defparam rom.INIT_RAM_24 = 256'h0C0C0C0E1F0E0C0D0E0E0F0F0F0F110F0200020E101010101010101010101010; + defparam rom.INIT_RAM_25 = 256'h0909090909090909090909090909070100010A0D0F110F0E0D0D0E141C1A110C; + defparam rom.INIT_RAM_26 = 256'h0C0C0C0C0C0C0E0F0E0E0D0D0D0D0E110F0200020E1010101010101010101010; + defparam rom.INIT_RAM_27 = 256'h090909090909090909090909090909060000030E0F11110F0F0F0F110F0D0C0C; + defparam rom.INIT_RAM_28 = 256'h0C0C0C0C0C0D0F110F0D0C0C0C0C0D0F110F0000010E10101010101010101010; + defparam rom.INIT_RAM_29 = 256'h090909080909090909080909090909080200000C11111111111111110F0D0C0C; + defparam rom.INIT_RAM_2A = 256'h0D0D0D0D0D0E0E0F0E0C0C0C0C0C0D0F1111080000010E101010101010101010; + defparam rom.INIT_RAM_2B = 256'h090909090909090909090909090909090600000411111111110F0F0F0E0E0D0D; + defparam rom.INIT_RAM_2C = 256'h0F0F0F0F0F0E0E0D0C060000000000000008110F0200010E1010101010101010; + defparam rom.INIT_RAM_2D = 256'h0A0A0A090909090909090909090909090900000011111108020C0D0D0E0E0F0F; + defparam rom.INIT_RAM_2E = 256'h11111111110F0D0C0C0000000000000000000F110F0000021010101010101010; + defparam rom.INIT_RAM_2F = 256'h0B0A0A0A0A0A0A090909090909090909090000001111110200010A0C0D0F1111; + defparam rom.INIT_RAM_30 = 256'h0F0F0F0F0F0E0D0C0C000000000000000000020F080000001010101010101010; + defparam rom.INIT_RAM_31 = 256'h0B0B0B0A0A0A0A0A0A0A0A0A0A0A090909000000111111000000010A0C0E0F0F; + defparam rom.INIT_RAM_32 = 256'h0D0D0D0D0D0D0C0C0C000000070F0F0C04000000000000001010101010101010; + defparam rom.INIT_RAM_33 = 256'h0C0C0C0C0C0C0C0C0B0B0B0B0B0B0A0A0A00000011111119190300010A0C0D0D; + defparam rom.INIT_RAM_34 = 256'h0C0C0C0C0C0C0C0C0C0000000F0F0F10100C0200000000001010101010101010; + defparam rom.INIT_RAM_35 = 256'h0D0D0D0D0D0C0C0C0C0C0C0C0C0B0B0B0B000000111111191915000001090C0C; + defparam rom.INIT_RAM_36 = 256'h0C0C0C0C0C0C0C0C0C0000000F0F0F1010100E02000000081010101010101010; + defparam rom.INIT_RAM_37 = 256'h0D0D0D0D0D0D0D0D0D0D0C0C0C0C0B0B0B0000001111111919190C0000000309; + defparam rom.INIT_RAM_38 = 256'h1919190000001919190000030F0F0F1010101010101010101010101010101010; + defparam rom.INIT_RAM_39 = 256'h0E0E0E0E0E0E0E0D0D0D0D0D0D0D0C0C0C0300000C111100000C191503000000; + defparam rom.INIT_RAM_3A = 256'h19191900000019191900000B0F0F0F1010101010101010101010101010101010; + defparam rom.INIT_RAM_3B = 256'h0E0E0E0E0E0E0E0E0E0D0D0D0D0D0D0D0D0A0000041111000000151915000000; + defparam rom.INIT_RAM_3C = 256'h0C190C0000000C190C00030D0E0F0F1010101010101010101010101010101010; + defparam rom.INIT_RAM_3D = 256'h0E0E0E0E0E0E0E0E0E0E0E0E0E0D0D0D0D0E0300000C1108000003150C000000; + defparam rom.INIT_RAM_3E = 256'h00000000000000000000090D0E0F0F1010101010101010101010101010101010; + defparam rom.INIT_RAM_3F = 256'h0E0E0E0E0F0F0F0F0F0F0E0E0E0E0E0E0E0E0A00000008110F02000000000000; +`endif // _img_vh_ diff --git a/examples/himbaechel/img-rom1.vh b/examples/himbaechel/img-rom1.vh new file mode 100644 index 00000000..c475c926 --- /dev/null +++ b/examples/himbaechel/img-rom1.vh @@ -0,0 +1,67 @@ +`ifndef _img1_vh_ +`define _img1_vh_ + defparam rom1.INIT_RAM_00 = 256'h000000000000040D111111111111111111111110101111111111111111111112; + defparam rom1.INIT_RAM_01 = 256'h1010101010101010101010101010101011111111111011110D04000000000000; + defparam rom1.INIT_RAM_02 = 256'h0000000000000000040F11111111111111111110101010111111111111111212; + defparam rom1.INIT_RAM_03 = 256'h101010101010101010101010101010101111111111100E040000000000000000; + defparam rom1.INIT_RAM_04 = 256'h000000000000000000020F111111111111111111111111111111111111111212; + defparam rom1.INIT_RAM_05 = 256'h1010101010101010101010111111101011111111100E02000000000000000000; + defparam rom1.INIT_RAM_06 = 256'h0D0D0D1F1F1F17070000020E1010111111111111111111111111111111111212; + defparam rom1.INIT_RAM_07 = 256'h10101010101010101111111111111111111111100E02000007070D0D0D141414; + defparam rom1.INIT_RAM_08 = 256'h0D0D0D1F1F1F1F1F170300020E10111111111111111111111111111111111212; + defparam rom1.INIT_RAM_09 = 256'h101010101010101011111111111111111110100E0200000607070D0D0D141414; + defparam rom1.INIT_RAM_0A = 256'h0D0F1D1F1F1F1F1F1F1B0300020E111111111111111111111111111111111112; + defparam rom1.INIT_RAM_0B = 256'h1010101010101010111111111111111111100E0200000607080C0D0D0D14130E; + defparam rom1.INIT_RAM_0C = 256'h0D1A1F1F1F1F1F1F1F1F1B0300020F1111111111111111111111111111111111; + defparam rom1.INIT_RAM_0D = 256'h111010101010101008000000020F1111110E0200000507070B0D0D1214100D0D; + defparam rom1.INIT_RAM_0E = 256'h111F1F1F1F1F1F1F1F1F1F1F0000021111111110101111111111111111111111; + defparam rom1.INIT_RAM_0F = 256'h11111010101010100000000000020F110F020000010707090D0D0F14140D0D0D; + defparam rom1.INIT_RAM_10 = 256'h1A1F1F1F1F1F1F1F1F1F1B030000001111111111111111111111111111111111; + defparam rom1.INIT_RAM_11 = 256'h11101010101010100000000000000211020000000507070B0D0D1214140D0D0D; + defparam rom1.INIT_RAM_12 = 256'h1F1F1F1F1F1F1F1F1F1B03000000001111111111111111111111111111111112; + defparam rom1.INIT_RAM_13 = 256'h10111011101010100000000A11020000000000000507070D0D0D1414140D0D0D; + defparam rom1.INIT_RAM_14 = 256'h1F1F1F1F1F1F1F1F1F0000000000001111111111111111111111111111111212; + defparam rom1.INIT_RAM_15 = 256'h10101111111010100200001114110000000000000107070D0D0D1414140D0D0D; + defparam rom1.INIT_RAM_16 = 256'h1F1F1F1F1F1F1F1F1F1B03000000001111111111111111111111111111111212; + defparam rom1.INIT_RAM_17 = 256'h10101111111010100E02000211141102000000000005070A0D0D1414140D0D0D; + defparam rom1.INIT_RAM_18 = 256'h1A1F1F1F1F1F1F1F1F1F1B030000001111111111111111111111111111111111; + defparam rom1.INIT_RAM_19 = 256'h1010101010101010100C0000000A1411020000000000060707071414140D0D0D; + defparam rom1.INIT_RAM_1A = 256'h111F1F1F1F1F1F1F1F1F1F1F0000001111111111111111111111111111111111; + defparam rom1.INIT_RAM_1B = 256'h10101010101010101010040000001414110500000000000607071414140D0D0D; + defparam rom1.INIT_RAM_1C = 256'h0D1A1F1F1F1F1F1F1F1F1F1F0000001111111111111111111111111111111111; + defparam rom1.INIT_RAM_1D = 256'h101010101010101010100C000000141413120C040000000007071414130E0E0D; + defparam rom1.INIT_RAM_1E = 256'h0D0F1D1F1F1F1F1F1F1D10100400000D11111111111111111111111111111111; + defparam rom1.INIT_RAM_1F = 256'h11111111101010101010100000001414131110100C0400000000141413100F0F; + defparam rom1.INIT_RAM_20 = 256'h0E0D0F1A1F1F1F1F1B1210100C00000411111111111111111111111111111111; + defparam rom1.INIT_RAM_21 = 256'h111111111110101010101000000014141311101010100C02000214141311100F; + defparam rom1.INIT_RAM_22 = 256'h0F0E0E0F131B1B1310100F11120500000D111111111111111111111111111111; + defparam rom1.INIT_RAM_23 = 256'h11111111101010101010080000001313121211111111100E0209131413121110; + defparam rom1.INIT_RAM_24 = 256'h100F0F0F10101010100F0E0E1311020004111111111111111111111111111111; + defparam rom1.INIT_RAM_25 = 256'h10101010100800000000000000000D1112121313131312101011131414131312; + defparam rom1.INIT_RAM_26 = 256'h11101010101010100F0E0D0D14141400000D1111111111111111111111111111; + defparam rom1.INIT_RAM_27 = 256'h1010101010000000000000000000041011131414141413111011131414141413; + defparam rom1.INIT_RAM_28 = 256'h1211111111111111100E0D0D1414140000041111111111111111111111111111; + defparam rom1.INIT_RAM_29 = 256'h1010111111000000000000000000000C10121313141413121112131414141413; + defparam rom1.INIT_RAM_2A = 256'h1313131313131313130707070707070000041111111111111111111111111111; + defparam rom1.INIT_RAM_2B = 256'h1010111111000000080E0200000000020E101112131414131313141414141414; + defparam rom1.INIT_RAM_2C = 256'h14141414141414141407070707070700000C1111111111111111111111111111; + defparam rom1.INIT_RAM_2D = 256'h10101111110200000E100E0400000000020E1011131414141414141414141414; + defparam rom1.INIT_RAM_2E = 256'h1414141414141414140D07070707030004111111111111111111111111111111; + defparam rom1.INIT_RAM_2F = 256'h10111111110F0200020E0F0F0903000000020E10121313141414141414141414; + defparam rom1.INIT_RAM_30 = 256'h141414141414141414141414000000020F111111111111111111111111111111; + defparam rom1.INIT_RAM_31 = 256'h1110111010110E020000070E0D0D07070300020E101112131414141414141414; + defparam rom1.INIT_RAM_32 = 256'h1414141414141414141414140000020F11111111111111111111111111111111; + defparam rom1.INIT_RAM_33 = 256'h111110101010100E0200000B0D0D070707000002101011131414141414141414; + defparam rom1.INIT_RAM_34 = 256'h14141414141414141414140A00020F1111111111111111111111121212121111; + defparam rom1.INIT_RAM_35 = 256'h11101010101010100E0200010D0D070703000000101011131414141414141414; + defparam rom1.INIT_RAM_36 = 256'h000000000000000000000000000D111111111111111111111212121212121211; + defparam rom1.INIT_RAM_37 = 256'h1011101110101010110F020000000000000000000C10111314140A0000000000; + defparam rom1.INIT_RAM_38 = 256'h0000000000000000000000000411111111111111111111111212121212121211; + defparam rom1.INIT_RAM_39 = 256'h101011111110101011110F040000000000000000041011131414000000000000; + defparam rom1.INIT_RAM_3A = 256'h0000000000000000000000000D11111111111111111111111212121212121211; + defparam rom1.INIT_RAM_3B = 256'h1011111111101010111111110C04000000000000000C101213140A0000000000; + defparam rom1.INIT_RAM_3C = 256'h14141414141414140A0000001111111111111111111111111212121212121111; + defparam rom1.INIT_RAM_3D = 256'h111111111110101010101010101011111111110800020E101112141414141414; + defparam rom1.INIT_RAM_3E = 256'h1414141414141414140000021010101111111111111111111111111111111111; + defparam rom1.INIT_RAM_3F = 256'h11111111111010101010101010101111111111110000020C1011131414141414; +`endif // _img1_vh_ diff --git a/examples/himbaechel/img-rom2.vh b/examples/himbaechel/img-rom2.vh new file mode 100644 index 00000000..6c4119fd --- /dev/null +++ b/examples/himbaechel/img-rom2.vh @@ -0,0 +1,67 @@ +`ifndef _img2_vh_ +`define _img2_vh_ + defparam rom2.INIT_RAM_00 = 288'h7E3E9F0F87C3F201048341A1104803F201068542209028242215067F3E9F90081412110A; + defparam rom2.INIT_RAM_01 = 288'h4825138A0552F990CE6C371C0E6753A9E0F27A3D9F4F87D3E9F4FA7C3D9E4F07A3F204FE; + defparam rom2.INIT_RAM_02 = 288'h7D3E1F0D60038209088341A09048040205088542209028242215067F3E9F90081412110A; + defparam rom2.INIT_RAM_03 = 288'h4A2593CA0542F188C869361B4E0713A1E0F67B3E1F0FA7E3F9FCFC5C0F000000010180FC; + defparam rom2.INIT_RAM_04 = 288'h6B3E1AC1E00081CD0A8441205028140A09088542209028242215067F3E9F90081412110A; + defparam rom2.INIT_RAM_05 = 288'h4B2613CA0542E184C668359B0DC6F391E0F87C3E1F0FA7F409C04000000000000000003C; + defparam rom2.INIT_RAM_06 = 288'h0F3E03C000000040E682401FCFE7F3FA0104834120D048341A1104803F1FD028241A110A; + defparam rom2.INIT_RAM_07 = 288'h4A259349E532D984C668359ACDA6E389D4F0783D1E8F67E3803C00000000000000000000; + defparam rom2.INIT_RAM_08 = 288'h00000003EFF0F80020703F1F4FA7D3E9F4FC7F40A09088341A090480402050684422150A; + defparam rom2.INIT_RAM_09 = 288'h482492C985015000000006974D66C369C4E4733A9D8EE6B078001862313FDFEFF5F8FC00; + defparam rom2.INIT_RAM_0A = 288'h1F0007DBEFF6F87C000F359F0F87C3E1F0FA7D3FA0D0A8441205028140A09088542A150C; + defparam rom2.INIT_RAM_0B = 288'h4724128964B00000000000034A06B361B8DE70399D0AC0E00030AA62313FDFEFF7FBFD7E; + defparam rom2.INIT_RAM_0C = 288'hDF0037DFEFF7FB7C3E00079ACFC7E3F1F8FC7F40A0D0A844120502824120D088542A150C; + defparam rom2.INIT_RAM_0D = 288'h4824924944A00000000000000001A289B8DE702A870000006154C47575BFDFEFF7FBFDFE; + defparam rom2.INIT_RAM_0E = 288'hFF7FBFDFEFF7FBFD7E0000079008241209068341A150A84412050483422110A8542A150C; + defparam rom2.INIT_RAM_0F = 288'h4A2492490480000000453C044000000000000000000000C2A988C4D77FBFDFEFF7FBFDFE; + defparam rom2.INIT_RAM_10 = 288'hFF7FBFDFEFF7FBFDFE3F00000C68542A150A8542A150C8541205048442A150A8542A150C; + defparam rom2.INIT_RAM_11 = 288'h4B251208E47040000078451E000000000000000000030553118910FF7FBFDFEFF7FBFDFE; + defparam rom2.INIT_RAM_12 = 288'hFF7FBFDFEFF7FBFDFEBF00000428341A0D068341A150A8441A090683422110884422110A; + defparam rom2.INIT_RAM_13 = 288'h4A2492490471E82000113C2288A000000000001119CEC6C31189AEFF7FBFDFEFF7FBFDFE; + defparam rom2.INIT_RAM_14 = 288'h7F001FDFEFF7FBFDFEFF00000005F3F9FCFE7F40A0D0A854221106834120904824120904; + defparam rom2.INIT_RAM_15 = 288'h48249249449238F4100000115148A45229148A45228FE6C31189FEFF7F9FC007F7FBFDFE; + defparam rom2.INIT_RAM_16 = 288'h0000001FEFF7FBFDFEFF00000001F3E9F4FA7D3FA0D0A8542A15088240A05028140A0502; + defparam rom2.INIT_RAM_17 = 288'h4724128964A2411C7A0800000F08A45229148A45228FE6C31189FEFF7F80000007FBFDFE; + defparam rom2.INIT_RAM_18 = 288'h7F001FDFEFF7FBFDFEFF0000000002E9F8FC7E4020D0A8542A15088240A0504824120904; + defparam rom2.INIT_RAM_19 = 288'h48249249449249208E3D0400022783F9FCFE7F45228FE6C31189FEFF7F9FC007F7FBFDFE; + defparam rom2.INIT_RAM_1A = 288'hFF7FBFDFEFF7FBFDFED7311881800079BD008040A110A8542A15088240A0906844221108; + defparam rom2.INIT_RAM_1B = 288'h4A2492490492492892471E8200011339B0D8763FA28FE6C31189AEFF7FBFDFEFF7FBFDFE; + defparam rom2.INIT_RAM_1C = 288'hFF7FBFDFEFF7FBFDFE8831188AA0C0003CE081412150C86432190A8240A09088542A150A; + defparam rom2.INIT_RAM_1D = 288'h4B251208E482512C9448238F4100006154C46C3FA28FE6C3118910FF7FBFDFEFF7FBFDFE; + defparam rom2.INIT_RAM_1E = 288'hFF7FBFDFEFF7FBFDAE62311B0D867088001E70412150C8642A1506834120D088542A150A; + defparam rom2.INIT_RAM_1F = 288'h4A2492490492512C9449241207E0900030AA623B1FCEC7636188C4D77FBFDFEFF7FBFDFE; + defparam rom2.INIT_RAM_20 = 288'hEB313ADFEFF7FBACEA623B1FCFE7F3C044000F39A150C8541A09068342A150A8542A150A; + defparam rom2.INIT_RAM_21 = 288'h4824924944A2592C964A251289441048001855311B0EC763F9D8C47575BFDFEFF7FBFDFE; + defparam rom2.INIT_RAM_22 = 288'h75311D5D6FF759D4C46C3FA29148A451E02200081D10C85412050485432190C86432190C; + defparam rom2.INIT_RAM_23 = 288'h4724128964B2592C964B2592C964B20824000C2A988D87F451FCD8623AB5DFEFF7FBFDAE; + defparam rom2.INIT_RAM_24 = 288'h6231188EAFF3A988D8763B1FCFE7F3FA28F01100040E88541205048342A150A8542A150A; + defparam rom2.INIT_RAM_25 = 288'h4824924944A2592C964A25128964B250FC100006154D87F451FCEC6C361D94EE16BA20C4; + defparam rom2.INIT_RAM_26 = 288'h6231188C462311D8FE763B1B0D86C361D9147808800207341205028241209048241A110A; + defparam rom2.INIT_RAM_27 = 288'h4A2492490492512C944924124944B25120680000060EC7F45228FE7F3F9FD147F36188C4; + defparam rom2.INIT_RAM_28 = 288'h6231188C462361FD147F36188C462311B0FE8A3C000000F38205028140A050281412110A; + defparam rom2.INIT_RAM_29 = 288'h4B251208E482512C944823920944B251208E1100000CE8A45229148A45229147F36188C4; + defparam rom2.INIT_RAM_2A = 288'h6C361B0D86C3B1D8FE7631188C462311B0FE8A451140000079C1048241209048241A110A; + defparam rom2.INIT_RAM_2B = 288'h4E26928924A25930964924124944B25124903500000448A45229148A3F9FCFE763B1B0D8; + defparam rom2.INIT_RAM_2C = 288'h7F3F9FCFE7F3B1D8D86218800000000000000022A28F0110003CE48442211088542A150A; + defparam rom2.INIT_RAM_2D = 288'h54291409C4E2793C9A4B25128964B25928944A00000008A452288A11339B0D8763B1FCFE; + defparam rom2.INIT_RAM_2E = 288'h8A45229148A3F9B0C462000000000000000000001E1147800000208542A150A86432190C; + defparam rom2.INIT_RAM_2F = 288'h582B148A050281409E4C2592C964B2592C964B00000008A45228220006154C46C3FA2914; + defparam rom2.INIT_RAM_30 = 288'h7F3F9FCFE7F3B1B0C46200000000000000000000044F04500000008542A150A86432150A; + defparam rom2.INIT_RAM_31 = 288'h5C2D164AE572A954A85328944A050281389C4E00000008A45228000000030AA623B1FCFE; + defparam rom2.INIT_RAM_32 = 288'h6C361B0D86C36188C46200000003E3E9FCC22100000000000000008542A150C8642A150A; + defparam rom2.INIT_RAM_33 = 288'h6633190C86331180C05F2F978B85B2C95CA85400000008A4522990C80C0001855311B0D8; + defparam rom2.INIT_RAM_34 = 288'h6231188C46231188C46200000007D3E9FD0685318400000000000086432190C8642A150A; + defparam rom2.INIT_RAM_35 = 288'h6B359ACD66A33998CC6633190C4612F168B05800000008A4522990C857000000C24988C4; + defparam rom2.INIT_RAM_36 = 288'h6231188C46231188C46200000007C3E1F90685429D02000000008485432190A854221108; + defparam rom2.INIT_RAM_37 = 288'h6D369B4DA6C359A8D4683419CCA643117CB85C00000008A4522990C86418C00000006092; + defparam rom2.INIT_RAM_38 = 288'hC86432000000032190C8000003A793C9F5048542A150C8542A150A854321506824120904; + defparam rom2.INIT_RAM_39 = 288'h72391C8E472389C4DE6E369B4D66B3519CCC660D000006745228000031B215C180000000; + defparam rom2.INIT_RAM_3A = 288'hC86432000000032190C800000B2783C1ED0486432190C8542A150A8543215048140A0502; + defparam rom2.INIT_RAM_3B = 288'h743A1D0E8743A1D0E670379BCDE6F371B0D66B280000022452280000002B990AE0000000; + defparam rom2.INIT_RAM_3C = 288'h636418C00000018D906300064DE733C1ED048542A150A854221108854321506824120904; + defparam rom2.INIT_RAM_3D = 288'h753A9D4EA753B1D8EA74391C8E070379B8DA6D38070000033A288A00000615C630000000; + defparam rom2.INIT_RAM_3E = 288'h0000000000000000000000130D4733C1ED048542A150A8441A090685432150884422110A; + defparam rom2.INIT_RAM_3F = 288'h773B9DCEE783C9ECF6793C9DCEA73399C8E4723915800000011514780880000000000000; +`endif // _img2_vh_ diff --git a/examples/himbaechel/img-rom3.vh b/examples/himbaechel/img-rom3.vh new file mode 100644 index 00000000..0f4825a9 --- /dev/null +++ b/examples/himbaechel/img-rom3.vh @@ -0,0 +1,67 @@ +`ifndef _img3_vh_ +`define _img3_vh_ + defparam rom3.INIT_RAM_00 = 288'h000000000000008CD48C45A25128944A29168C452210C8644221148B462311C8E47A3D20; + defparam rom3.INIT_RAM_01 = 288'h8542A150A85432190C86432190A8542A190C8845231148843221146A1180000000000000; + defparam rom3.INIT_RAM_02 = 288'h000000000000000000223C229148A4522D188E462210C8643219108C472391C8E47A4926; + defparam rom3.INIT_RAM_03 = 288'h8542A150C86432190C86432190C86432190C88462391888431D042000000000000000000; + defparam rom3.INIT_RAM_04 = 288'h00000000000000000000081E1128944A29188E46229108844221148C472391C8E47A4926; + defparam rom3.INIT_RAM_05 = 288'h8542A150C86432190C8743A1D10884421D0E894523114863A04000000000000000000000; + defparam rom3.INIT_RAM_06 = 288'h6B359ADFEFF7FAFC7E0000040EC8743A25188E47231188C46231188F47A3D1C8E47A4926; + defparam rom3.INIT_RAM_07 = 288'h8542A150C86432190E8844A29168C45A29128844A210C74080000C3D1E9ACD66B51A8D46; + defparam rom3.INIT_RAM_08 = 288'h6B359ADFEFF7FBFDFEBF0F800207443221188E472391C8E472391C8F47A3D1C8E47A4926; + defparam rom3.INIT_RAM_09 = 288'h8542A150C86432190E894522D188E4622D148943A18E810000186A3D1E9ACD66B51A8D46; + defparam rom3.INIT_RAM_0A = 288'h6B3D3ADFEFF7FBFDFEFF6F87C00103A221188E47231188C462311A8F47A3D1A8C4723D20; + defparam rom3.INIT_RAM_0B = 288'h86432150A8542A150C884522D188E4622D1489439D02000030D47A43329ACD66B51A6CE4; + defparam rom3.INIT_RAM_0C = 288'h6B6BBFDFEFF7FBFDFEFF7FB7C3E00081E1188E4622910894522D188D47A35188B45A3118; + defparam rom3.INIT_RAM_0D = 288'h8843A190A8542A150C430000000113D22D14893B0400000168F47A5F359AD28A3431ACD6; + defparam rom3.INIT_RAM_0E = 288'h8B7FBFDFEFF7FBFDFEFF7FBFDFE00000451C8E462210C8744A29168D47A35168A4522914; + defparam rom3.INIT_RAM_0F = 288'h8A442190A8542A150A00000000000081E1147808000000E1E8F4926B359E146A3359ACD6; + defparam rom3.INIT_RAM_10 = 288'hD77FBFDFEFF7FBFDFEFF7FB7C3E0000001188C45A2910894522D188D47A35188B45A3118; + defparam rom3.INIT_RAM_11 = 288'h8943A1D0C8642A150A0000000000000041141000000002D1E8F4BE6B35A5146A3359ACD6; + defparam rom3.INIT_RAM_12 = 288'hFF7FBFDFEFF7FBFDFEFF6F87C000000001168B4622D188C46A31188E47239188C4723D20; + defparam rom3.INIT_RAM_13 = 288'h874421D1087432150A0000000A28E09800000000000002D1E8F4D66B35A8D46A3359ACD6; + defparam rom3.INIT_RAM_14 = 288'hFF7FBFDFEFF7FBFDFEFF00000000000001148A45A351E8F472391C8E472391C8E47A4926; + defparam rom3.INIT_RAM_15 = 288'h8643A25148943A190C10000011CA347000000000000000E1E8F4D66B35A8D46A3359ACD6; + defparam rom3.INIT_RAM_16 = 288'hFF7FBFDFEFF7FBFDFEFF6F87C000000001148A45A351E8F46A31188E47239188C4724524; + defparam rom3.INIT_RAM_17 = 288'h8643A21128843A190C7408000268E51A382600000000000168F4A86B35A8D46A3359ACD6; + defparam rom3.INIT_RAM_18 = 288'hD77FBFDFEFF7FBFDFEFF7FB7C3E0000001148A45A351E8D4622D188D47A35188B462391E; + defparam rom3.INIT_RAM_19 = 288'h864321D0E87432190C8632000000028A8D1C13000000000030D47A3D1EA8D46A3359ACD6; + defparam rom3.INIT_RAM_1A = 288'h8B7FBFDFEFF7FBFDFEFF7FBFDFE0000001148A45A351E8D45A29168D47A35168A45A311C; + defparam rom3.INIT_RAM_1B = 288'h86432190C86432190C864308400000028D468E140000000000186A3D1EA8D46A3359ACD6; + defparam rom3.INIT_RAM_1C = 288'h6B6BBFDFEFF7FBFDFEFF7FBFDFE0000001168B462351E8D4622D188C46A31188B462311C; + defparam rom3.INIT_RAM_1D = 288'h8743A1D0E8742A150A864319000000028D469B4998C4000000000C3D1EA8D469B389C4D6; + defparam rom3.INIT_RAM_1E = 288'h6B3D3ADFEFF7FBFDFEFF772150A2000000D48D46A3D1E8F46A35188C45A31188C462391C; + defparam rom3.INIT_RAM_1F = 288'h8944A251287432150A854321800000028D469B462150A631000000000028D469B429F8F0; + defparam rom3.INIT_RAM_20 = 288'h71359E9AEFF7FBFDFEDD48A150A6300000468F47A3D1E8F47A3D1A8B4522D188E472391C; + defparam rom3.INIT_RAM_21 = 288'h8A452291488432150A854321800000028D469B462150A854298C200009A8D469B46214FC; + defparam rom3.INIT_RAM_22 = 288'h78389C4F09F6EB753E85429F9189314000006B47A3D1E8F46A35188B4522D188C462391C; + defparam rom3.INIT_RAM_23 = 288'h8944A25128742A150A854310800000026D369349A31188C46214E61024A6D469B49A310A; + defparam rom3.INIT_RAM_24 = 288'h853F1F8FC8542A150A853C1C4E29B4704C002347A3D1E8D4622D168A45229168B462311C; + defparam rom3.INIT_RAM_25 = 288'h8743A1D0E85210000000000000000001AD189349A6D369B4DA4D0A854626D46A34DA6D26; + defparam rom3.INIT_RAM_26 = 288'h8C42A150A8542A150A7E389ACD6A351A8C000035A3D1E8D45A29148A45229148A45A311C; + defparam rom3.INIT_RAM_27 = 288'h86432190C86000000000000000000000810A8C4DA8D46A351A6D18854626D46A351A8D36; + defparam rom3.INIT_RAM_28 = 288'h9346231188C462311885389ACD6A351A8C000011A351A8C4622D168B45A2D148A45A311C; + defparam rom3.INIT_RAM_29 = 288'h8542A21108800000000000000000000000C68549A6D36A351A6D268C49A6D46A351A8D36; + defparam rom3.INIT_RAM_2A = 288'h9B4DA6D369B4DA6D369B1E8F47A3D1E8F400001122D168C462351A8D46231168A45A311C; + defparam rom3.INIT_RAM_2B = 288'h8543A25188C00000004139840000000000207342A31269B51A8D369B4DA8D46A351A8D46; + defparam rom3.INIT_RAM_2C = 288'hA351A8D46A351A8D46A31E8F47A3D1E8F4000033229148B46A3D1E8E47231168A45A311C; + defparam rom3.INIT_RAM_2D = 288'h8543A2D1C8E088000073429CC400000000001039A15189B51A8D46A351A8D46A351A8D46; + defparam rom3.INIT_RAM_2E = 288'hA351A8D46A351A8D46A3378F47A3D1E87800234622D168C46A3D1E8E47231188B462311C; + defparam rom3.INIT_RAM_2F = 288'h8644225168C3C0400010399F8F04F0D0000000081CD0A934DA6D46A351A8D46A351A8D46; + defparam rom3.INIT_RAM_30 = 288'hA351A8D46A351A8D46A351A8D460000000227C462351A8D47A391C8E472391A8D46A391C; + defparam rom3.INIT_RAM_31 = 288'h8843A210E87441D02000000ECE26B358F47A1E00040E6854624D36A351A8D46A351A8D46; + defparam rom3.INIT_RAM_32 = 288'hA351A8D46A351A8D46A351A8D460000044F88E4723D1E8F472391C8E472391E8F47A391C; + defparam rom3.INIT_RAM_33 = 288'h8A442190A8542A18E81000000BA6B358F47A3D00000208542A3136A351A8D46A351A8D46; + defparam rom3.INIT_RAM_34 = 288'hA351A8D46A351A8D46A351A8CA200089F11C8C46A3D1E8F472391C8F47A4120904823D1C; + defparam rom3.INIT_RAM_35 = 288'h8943A1D0C8642A190E7608000186B358F47A1E00000008542A3136A351A8D46A351A8D46; + defparam rom3.INIT_RAM_36 = 288'h0000000000000000000000000000035239188B462351C8E472391E9149249249248A411E; + defparam rom3.INIT_RAM_37 = 288'h874421D108743A190E893C040000000000000000000006342A3136A35194400000000000; + defparam rom3.INIT_RAM_38 = 288'h0000000000000000000000000002347231168A45A311C8E472391E9249A4D2693492411E; + defparam rom3.INIT_RAM_39 = 288'h8643A25148943A190E89451E0440000000000000000002042A3136A35180000000000000; + defparam rom3.INIT_RAM_3A = 288'h000000000000000000000000000684622D168A45A351C8E472391E9149249249248A411E; + defparam rom3.INIT_RAM_3B = 288'h8744225148943A190E8844A25106410800000000000000031A15269B5194400000000000; + defparam rom3.INIT_RAM_3C = 288'hA351A8D46A351A8D465100000008844225128A45A351E8F472391C904824120904823D1E; + defparam rom3.INIT_RAM_3D = 288'h8944A29148943A190C8743A1D0E8643A25148B462388E00081CD0A8C49A8D46A351A8D46; + defparam rom3.INIT_RAM_3E = 288'hA351A8D46A351A8D46A30000020864321D128A45A351E8F472391C8F47A3D1E8F47A3D1E; + defparam rom3.INIT_RAM_3F = 288'h8A45229148943A190C86432190C8643A25148B462391C0000040C6854626D46A351A8D46; +`endif // _img3_vh_ diff --git a/examples/himbaechel/img-video-ram.vh b/examples/himbaechel/img-video-ram.vh new file mode 100644 index 00000000..ef074d66 --- /dev/null +++ b/examples/himbaechel/img-video-ram.vh @@ -0,0 +1,67 @@ +`ifndef _img_ram_vh_ +`define _img_ram_vh_ + defparam mem.INIT_RAM_00 = 256'h0F0F0F0F0F0F101010101010100F101010101010101010100F0F0F1010101010; + defparam mem.INIT_RAM_01 = 256'h0909090A0A0B0C0C0D0D0E0E0E0E0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F100F; + defparam mem.INIT_RAM_02 = 256'h0F0F0F0D000E1010101010101010101010101010101010100F0F0F1010101010; + defparam mem.INIT_RAM_03 = 256'h0909090A0A0B0C0C0D0D0D0E0E0E0F0F0F0F0F0F0F0F0F0F0B03000000040C0F; + defparam mem.INIT_RAM_04 = 256'h0D0F0D0100020E10101010101010101010101010101010100F0F0F1010101010; + defparam mem.INIT_RAM_05 = 256'h0909090A0A0B0C0C0D0D0D0D0D0E0F0F0F0F0F0F0F100E040000000000000003; + defparam mem.INIT_RAM_06 = 256'h010F01000000020E10100F0F0F0F10101010101010101010100F0F1010101010; + defparam mem.INIT_RAM_07 = 256'h090909090A0B0C0C0D0D0D0D0D0E0E0F0F0F0F0F0F0E01000000000000000000; + defparam mem.INIT_RAM_08 = 256'h000000031F0300020E0F0F0F0F0F0F0F0F101010101010101010101010101010; + defparam mem.INIT_RAM_09 = 256'h090909090A05000000010B0D0D0D0E0E0E0E0E0E0D0100010C0C1F1F1F170700; + defparam mem.INIT_RAM_0A = 256'h0300031B1F1B0300010D0F0F0F0F0F0F0F0F1010101010101010101010101010; + defparam mem.INIT_RAM_0B = 256'h08090909090000000000010A0D0D0D0D0E0E0E0A0100010A0C0C1F1F1F1F1F17; + defparam mem.INIT_RAM_0C = 256'h1B001B1F1F1F1B0300010D0F0F0F0F0F0F101010101010101010101010101010; + defparam mem.INIT_RAM_0D = 256'h090909090900000000000000030A0D0D0E0A030000010A0C0E1D1F1F1F1F1F1F; + defparam mem.INIT_RAM_0E = 256'h1F1F1F1F1F1F1F17000003101010101010101010101010101010101010101010; + defparam mem.INIT_RAM_0F = 256'h0909090909000000080F02000000000000000000010A0C0C1A1F1F1F1F1F1F1F; + defparam mem.INIT_RAM_10 = 256'h1F1F1F1F1F1F1F1F0700000C1010101010101010101010101010101010101010; + defparam mem.INIT_RAM_11 = 256'h09090908080100000F110F0000000000000000030A0C0C111F1F1F1F1F1F1F1F; + defparam mem.INIT_RAM_12 = 256'h1F1F1F1F1F1F1F1F170000041010101010101010101010101010101010101010; + defparam mem.INIT_RAM_13 = 256'h0909090908070100020F11080000000000040C0E0D0C0C1A1F1F1F1F1F1F1F1F; + defparam mem.INIT_RAM_14 = 256'h0F000F1F1F1F1F1F1F0000000B0F0F0F0F101010101010101010101010101010; + defparam mem.INIT_RAM_15 = 256'h090909090908070100000811111111111111110F0D0C0C1F1F1F0F000F1F1F1F; + defparam mem.INIT_RAM_16 = 256'h0000001F1F1F1F1F1F000000030F0F0F0F0F1010101010101010101010101010; + defparam mem.INIT_RAM_17 = 256'h08090909090908070100000F111111111111110F0D0C0C1F1F1F0000001F1F1F; + defparam mem.INIT_RAM_18 = 256'h0F000F1F1F1F1F1F1F000000000B0F0F0F101010101010101010101010101010; + defparam mem.INIT_RAM_19 = 256'h0909090909090908070100020F0F0F0F0F11110F0D0C0C1F1F1F0F000F1F1F1F; + defparam mem.INIT_RAM_1A = 256'h1F1F1F1F1F1F1F1F1A0C0C0100010D1010101010101010101010101010101010; + defparam mem.INIT_RAM_1B = 256'h090909090909090908070100020C0D0D0E0F110F0D0C0C1A1F1F1F1F1F1F1F1F; + defparam mem.INIT_RAM_1C = 256'h1F1F1F1F1F1F1F1F110C0C0A0100010E10101010101010101010101010101010; + defparam mem.INIT_RAM_1D = 256'h09090908090909090908070100010A0C0D0F110F0D0C0C111F1F1F1F1F1F1F1F; + defparam mem.INIT_RAM_1E = 256'h1F1F1F1F1F1F1F1A0C0C0D0D0C0200010E101010101010101010101010101010; + defparam mem.INIT_RAM_1F = 256'h0909090909090909090909070100010A0C0E0F0E0E0D0C0C1A1F1F1F1F1F1F1F; + defparam mem.INIT_RAM_20 = 256'h1D0C1D1F1F1F1D0E0C0E0F0F0F0F0200010E1010101010101010101010101010; + defparam mem.INIT_RAM_21 = 256'h090909090909090909090909080100010A0C0D0E0E0F0E0C0E1D1F1F1F1F1F1F; + defparam mem.INIT_RAM_22 = 256'h0E0C0E1D1F1D0E0C0D0F111111110F0200020E10101010101010101010101010; + defparam mem.INIT_RAM_23 = 256'h08090909090909090909090909080100010A0C0D0F110F0D0C0E1A1F1F1F1F1A; + defparam mem.INIT_RAM_24 = 256'h0C0C0C0E1F0E0C0D0E0E0F0F0F0F110F0200020E101010101010101010101010; + defparam mem.INIT_RAM_25 = 256'h0909090909090909090909090909070100010A0D0F110F0E0D0D0E141C1A110C; + defparam mem.INIT_RAM_26 = 256'h0C0C0C0C0C0C0E0F0E0E0D0D0D0D0E110F0200020E1010101010101010101010; + defparam mem.INIT_RAM_27 = 256'h090909090909090909090909090909060000030E0F11110F0F0F0F110F0D0C0C; + defparam mem.INIT_RAM_28 = 256'h0C0C0C0C0C0D0F110F0D0C0C0C0C0D0F110F0000010E10101010101010101010; + defparam mem.INIT_RAM_29 = 256'h090909080909090909080909090909080200000C11111111111111110F0D0C0C; + defparam mem.INIT_RAM_2A = 256'h0D0D0D0D0D0E0E0F0E0C0C0C0C0C0D0F1111080000010E101010101010101010; + defparam mem.INIT_RAM_2B = 256'h090909090909090909090909090909090600000411111111110F0F0F0E0E0D0D; + defparam mem.INIT_RAM_2C = 256'h0F0F0F0F0F0E0E0D0C060000000000000008110F0200010E1010101010101010; + defparam mem.INIT_RAM_2D = 256'h0A0A0A090909090909090909090909090900000011111108020C0D0D0E0E0F0F; + defparam mem.INIT_RAM_2E = 256'h11111111110F0D0C0C0000000000000000000F110F0000021010101010101010; + defparam mem.INIT_RAM_2F = 256'h0B0A0A0A0A0A0A090909090909090909090000001111110200010A0C0D0F1111; + defparam mem.INIT_RAM_30 = 256'h0F0F0F0F0F0E0D0C0C000000000000000000020F080000001010101010101010; + defparam mem.INIT_RAM_31 = 256'h0B0B0B0A0A0A0A0A0A0A0A0A0A0A090909000000111111000000010A0C0E0F0F; + defparam mem.INIT_RAM_32 = 256'h0D0D0D0D0D0D0C0C0C000000070F0F0C04000000000000001010101010101010; + defparam mem.INIT_RAM_33 = 256'h0C0C0C0C0C0C0C0C0B0B0B0B0B0B0A0A0A00000011111119190300010A0C0D0D; + defparam mem.INIT_RAM_34 = 256'h0C0C0C0C0C0C0C0C0C0000000F0F0F10100C0200000000001010101010101010; + defparam mem.INIT_RAM_35 = 256'h0D0D0D0D0D0C0C0C0C0C0C0C0C0B0B0B0B000000111111191915000001090C0C; + defparam mem.INIT_RAM_36 = 256'h0C0C0C0C0C0C0C0C0C0000000F0F0F1010100E02000000081010101010101010; + defparam mem.INIT_RAM_37 = 256'h0D0D0D0D0D0D0D0D0D0D0C0C0C0C0B0B0B0000001111111919190C0000000309; + defparam mem.INIT_RAM_38 = 256'h1919190000001919190000030F0F0F1010101010101010101010101010101010; + defparam mem.INIT_RAM_39 = 256'h0E0E0E0E0E0E0E0D0D0D0D0D0D0D0C0C0C0300000C111100000C191503000000; + defparam mem.INIT_RAM_3A = 256'h19191900000019191900000B0F0F0F1010101010101010101010101010101010; + defparam mem.INIT_RAM_3B = 256'h0E0E0E0E0E0E0E0E0E0D0D0D0D0D0D0D0D0A0000041111000000151915000000; + defparam mem.INIT_RAM_3C = 256'h0C190C0000000C190C00030D0E0F0F1010101010101010101010101010101010; + defparam mem.INIT_RAM_3D = 256'h0E0E0E0E0E0E0E0E0E0E0E0E0E0D0D0D0D0E0300000C1108000003150C000000; + defparam mem.INIT_RAM_3E = 256'h00000000000000000000090D0E0F0F1010101010101010101010101010101010; + defparam mem.INIT_RAM_3F = 256'h0E0E0E0E0F0F0F0F0F0F0E0E0E0E0E0E0E0E0A00000008110F02000000000000; +`endif // _img_ram_h_ diff --git a/examples/himbaechel/img-video-ram1.vh b/examples/himbaechel/img-video-ram1.vh new file mode 100644 index 00000000..5a757922 --- /dev/null +++ b/examples/himbaechel/img-video-ram1.vh @@ -0,0 +1,67 @@ +`ifndef _img_ram_vh_ +`define _img_ram_vh_ + defparam mem.INIT_RAM_00 = 288'h000000000000008CD48C45A25128944A29168C452210C8644221148B462311C8E47A3D20; + defparam mem.INIT_RAM_01 = 288'h8542A150A85432190C86432190A8542A190C8845231148843221146A1180000000000000; + defparam mem.INIT_RAM_02 = 288'h000000000000000000223C229148A4522D188E462210C8643219108C472391C8E47A4926; + defparam mem.INIT_RAM_03 = 288'h8542A150C86432190C86432190C86432190C88462391888431D042000000000000000000; + defparam mem.INIT_RAM_04 = 288'h00000000000000000000081E1128944A29188E46229108844221148C472391C8E47A4926; + defparam mem.INIT_RAM_05 = 288'h8542A150C86432190C8743A1D10884421D0E894523114863A04000000000000000000000; + defparam mem.INIT_RAM_06 = 288'h6B359ADFEFF7FAFC7E0000040EC8743A25188E47231188C46231188F47A3D1C8E47A4926; + defparam mem.INIT_RAM_07 = 288'h8542A150C86432190E8844A29168C45A29128844A210C74080000C3D1E9ACD66B51A8D46; + defparam mem.INIT_RAM_08 = 288'h6B359ADFEFF7FBFDFEBF0F800207443221188E472391C8E472391C8F47A3D1C8E47A4926; + defparam mem.INIT_RAM_09 = 288'h8542A150C86432190E894522D188E4622D148943A18E810000186A3D1E9ACD66B51A8D46; + defparam mem.INIT_RAM_0A = 288'h6B3D3ADFEFF7FBFDFEFF6F87C00103A221188E47231188C462311A8F47A3D1A8C4723D20; + defparam mem.INIT_RAM_0B = 288'h86432150A8542A150C884522D188E4622D1489439D02000030D47A43329ACD66B51A6CE4; + defparam mem.INIT_RAM_0C = 288'h6B6BBFDFEFF7FBFDFEFF7FB7C3E00081E1188E4622910894522D188D47A35188B45A3118; + defparam mem.INIT_RAM_0D = 288'h8843A190A8542A150C430000000113D22D14893B0400000168F47A5F359AD28A3431ACD6; + defparam mem.INIT_RAM_0E = 288'h8B7FBFDFEFF7FBFDFEFF7FBFDFE00000451C8E462210C8744A29168D47A35168A4522914; + defparam mem.INIT_RAM_0F = 288'h8A442190A8542A150A00000000000081E1147808000000E1E8F4926B359E146A3359ACD6; + defparam mem.INIT_RAM_10 = 288'hD77FBFDFEFF7FBFDFEFF7FB7C3E0000001188C45A2910894522D188D47A35188B45A3118; + defparam mem.INIT_RAM_11 = 288'h8943A1D0C8642A150A0000000000000041141000000002D1E8F4BE6B35A5146A3359ACD6; + defparam mem.INIT_RAM_12 = 288'hFF7FBFDFEFF7FBFDFEFF6F87C000000001168B4622D188C46A31188E47239188C4723D20; + defparam mem.INIT_RAM_13 = 288'h874421D1087432150A0000000A28E09800000000000002D1E8F4D66B35A8D46A3359ACD6; + defparam mem.INIT_RAM_14 = 288'hFF7FBFDFEFF7FBFDFEFF00000000000001148A45A351E8F472391C8E472391C8E47A4926; + defparam mem.INIT_RAM_15 = 288'h8643A25148943A190C10000011CA347000000000000000E1E8F4D66B35A8D46A3359ACD6; + defparam mem.INIT_RAM_16 = 288'hFF7FBFDFEFF7FBFDFEFF6F87C000000001148A45A351E8F46A31188E47239188C4724524; + defparam mem.INIT_RAM_17 = 288'h8643A21128843A190C7408000268E51A382600000000000168F4A86B35A8D46A3359ACD6; + defparam mem.INIT_RAM_18 = 288'hD77FBFDFEFF7FBFDFEFF7FB7C3E0000001148A45A351E8D4622D188D47A35188B462391E; + defparam mem.INIT_RAM_19 = 288'h864321D0E87432190C8632000000028A8D1C13000000000030D47A3D1EA8D46A3359ACD6; + defparam mem.INIT_RAM_1A = 288'h8B7FBFDFEFF7FBFDFEFF7FBFDFE0000001148A45A351E8D45A29168D47A35168A45A311C; + defparam mem.INIT_RAM_1B = 288'h86432190C86432190C864308400000028D468E140000000000186A3D1EA8D46A3359ACD6; + defparam mem.INIT_RAM_1C = 288'h6B6BBFDFEFF7FBFDFEFF7FBFDFE0000001168B462351E8D4622D188C46A31188B462311C; + defparam mem.INIT_RAM_1D = 288'h8743A1D0E8742A150A864319000000028D469B4998C4000000000C3D1EA8D469B389C4D6; + defparam mem.INIT_RAM_1E = 288'h6B3D3ADFEFF7FBFDFEFF772150A2000000D48D46A3D1E8F46A35188C45A31188C462391C; + defparam mem.INIT_RAM_1F = 288'h8944A251287432150A854321800000028D469B462150A631000000000028D469B429F8F0; + defparam mem.INIT_RAM_20 = 288'h71359E9AEFF7FBFDFEDD48A150A6300000468F47A3D1E8F47A3D1A8B4522D188E472391C; + defparam mem.INIT_RAM_21 = 288'h8A452291488432150A854321800000028D469B462150A854298C200009A8D469B46214FC; + defparam mem.INIT_RAM_22 = 288'h78389C4F09F6EB753E85429F9189314000006B47A3D1E8F46A35188B4522D188C462391C; + defparam mem.INIT_RAM_23 = 288'h8944A25128742A150A854310800000026D369349A31188C46214E61024A6D469B49A310A; + defparam mem.INIT_RAM_24 = 288'h853F1F8FC8542A150A853C1C4E29B4704C002347A3D1E8D4622D168A45229168B462311C; + defparam mem.INIT_RAM_25 = 288'h8743A1D0E85210000000000000000001AD189349A6D369B4DA4D0A854626D46A34DA6D26; + defparam mem.INIT_RAM_26 = 288'h8C42A150A8542A150A7E389ACD6A351A8C000035A3D1E8D45A29148A45229148A45A311C; + defparam mem.INIT_RAM_27 = 288'h86432190C86000000000000000000000810A8C4DA8D46A351A6D18854626D46A351A8D36; + defparam mem.INIT_RAM_28 = 288'h9346231188C462311885389ACD6A351A8C000011A351A8C4622D168B45A2D148A45A311C; + defparam mem.INIT_RAM_29 = 288'h8542A21108800000000000000000000000C68549A6D36A351A6D268C49A6D46A351A8D36; + defparam mem.INIT_RAM_2A = 288'h9B4DA6D369B4DA6D369B1E8F47A3D1E8F400001122D168C462351A8D46231168A45A311C; + defparam mem.INIT_RAM_2B = 288'h8543A25188C00000004139840000000000207342A31269B51A8D369B4DA8D46A351A8D46; + defparam mem.INIT_RAM_2C = 288'hA351A8D46A351A8D46A31E8F47A3D1E8F4000033229148B46A3D1E8E47231168A45A311C; + defparam mem.INIT_RAM_2D = 288'h8543A2D1C8E088000073429CC400000000001039A15189B51A8D46A351A8D46A351A8D46; + defparam mem.INIT_RAM_2E = 288'hA351A8D46A351A8D46A3378F47A3D1E87800234622D168C46A3D1E8E47231188B462311C; + defparam mem.INIT_RAM_2F = 288'h8644225168C3C0400010399F8F04F0D0000000081CD0A934DA6D46A351A8D46A351A8D46; + defparam mem.INIT_RAM_30 = 288'hA351A8D46A351A8D46A351A8D460000000227C462351A8D47A391C8E472391A8D46A391C; + defparam mem.INIT_RAM_31 = 288'h8843A210E87441D02000000ECE26B358F47A1E00040E6854624D36A351A8D46A351A8D46; + defparam mem.INIT_RAM_32 = 288'hA351A8D46A351A8D46A351A8D460000044F88E4723D1E8F472391C8E472391E8F47A391C; + defparam mem.INIT_RAM_33 = 288'h8A442190A8542A18E81000000BA6B358F47A3D00000208542A3136A351A8D46A351A8D46; + defparam mem.INIT_RAM_34 = 288'hA351A8D46A351A8D46A351A8CA200089F11C8C46A3D1E8F472391C8F47A4120904823D1C; + defparam mem.INIT_RAM_35 = 288'h8943A1D0C8642A190E7608000186B358F47A1E00000008542A3136A351A8D46A351A8D46; + defparam mem.INIT_RAM_36 = 288'h0000000000000000000000000000035239188B462351C8E472391E9149249249248A411E; + defparam mem.INIT_RAM_37 = 288'h874421D108743A190E893C040000000000000000000006342A3136A35194400000000000; + defparam mem.INIT_RAM_38 = 288'h0000000000000000000000000002347231168A45A311C8E472391E9249A4D2693492411E; + defparam mem.INIT_RAM_39 = 288'h8643A25148943A190E89451E0440000000000000000002042A3136A35180000000000000; + defparam mem.INIT_RAM_3A = 288'h000000000000000000000000000684622D168A45A351C8E472391E9149249249248A411E; + defparam mem.INIT_RAM_3B = 288'h8744225148943A190E8844A25106410800000000000000031A15269B5194400000000000; + defparam mem.INIT_RAM_3C = 288'hA351A8D46A351A8D465100000008844225128A45A351E8F472391C904824120904823D1E; + defparam mem.INIT_RAM_3D = 288'h8944A29148943A190C8743A1D0E8643A25148B462388E00081CD0A8C49A8D46A351A8D46; + defparam mem.INIT_RAM_3E = 288'hA351A8D46A351A8D46A30000020864321D128A45A351E8F472391C8F47A3D1E8F47A3D1E; + defparam mem.INIT_RAM_3F = 288'h8A45229148943A190C86432190C8643A25148B462391C0000040C6854626D46A351A8D46; +`endif // _img_ram_vh_ diff --git a/examples/himbaechel/pROM-image-rom.v b/examples/himbaechel/pROM-image-rom.v new file mode 100644 index 00000000..ffbb25eb --- /dev/null +++ b/examples/himbaechel/pROM-image-rom.v @@ -0,0 +1,44 @@ +`default_nettype none +module image_rom( + input wire clk, + input wire reset, + input wire [11:0] ad, + output wire [7:0] data +); + + wire gnd, vcc; + assign gnd = 1'b0; + assign vcc = 1'b1; + + wire [23:0] dummy_w [1:0]; + wire [7:0] data_w [1:0]; + assign data = data_w[ad[11]]; + + pROM rom( + .AD({ad[10:0], gnd, gnd, gnd}), + .DO({dummy_w[0], data_w[0]}), + .CLK(clk), + .OCE(vcc), + .CE(vcc), + .RESET(reset) + ); + defparam rom.READ_MODE = 1'b1; + defparam rom.BIT_WIDTH = 8; + defparam rom.RESET_MODE = "SYNC"; +`include "img-rom.vh" + + pROM rom1( + .AD({ad[10:0], gnd, gnd, gnd}), + .DO({dummy_w[1], data_w[1]}), + .CLK(clk), + .OCE(vcc), + .CE(vcc), + .RESET(reset) + ); + defparam rom1.READ_MODE = 1'b1; + defparam rom1.BIT_WIDTH = 8; + defparam rom1.RESET_MODE = "SYNC"; +`include "img-rom1.vh" + +endmodule + diff --git a/examples/himbaechel/pROM-video-ram.v b/examples/himbaechel/pROM-video-ram.v new file mode 100644 index 00000000..ef37f263 --- /dev/null +++ b/examples/himbaechel/pROM-video-ram.v @@ -0,0 +1,2 @@ +/* empty */ + diff --git a/examples/himbaechel/pROM.v b/examples/himbaechel/pROM.v new file mode 100644 index 00000000..55248870 --- /dev/null +++ b/examples/himbaechel/pROM.v @@ -0,0 +1,146 @@ +`default_nettype none +(* top *) +module top +( + input wire rst_i, + input wire clk, + + output wire LCD_CLK, + output wire LCD_HYNC, + output wire LCD_SYNC, + output wire LCD_DEN, + output wire [4:0] LCD_R, + output wire [5:0] LCD_G, + output wire [4:0] LCD_B +); + + wire rst = rst_i ^ `INV_BTN; + wire pixel_clk; + wire gnd; + assign gnd = 1'b0; + + rPLL pll( + .CLKOUT(pixel_clk), // 9MHz + .CLKIN(clk), + .CLKFB(gnd), + .RESET(!rst), + .RESET_P(!rst), + .FBDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .IDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .ODSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .DUTYDA({gnd, gnd, gnd, gnd}), + .PSDA({gnd, gnd, gnd, gnd}), + .FDLY({gnd, gnd, gnd, gnd}) + ); + defparam pll.DEVICE = `PLL_DEVICE; + defparam pll.FCLKIN = `PLL_FCLKIN; + defparam pll.FBDIV_SEL = `PLL_FBDIV_SEL_LCD; + defparam pll.IDIV_SEL = `PLL_IDIV_SEL_LCD; + defparam pll.ODIV_SEL = `PLL_ODIV_SEL; + defparam pll.CLKFB_SEL="internal"; + defparam pll.CLKOUTD3_SRC="CLKOUT"; + defparam pll.CLKOUTD_BYPASS="false"; + defparam pll.CLKOUTD_SRC="CLKOUT"; + defparam pll.CLKOUTP_BYPASS="false"; + defparam pll.CLKOUTP_DLY_STEP=0; + defparam pll.CLKOUTP_FT_DIR=1'b1; + defparam pll.CLKOUT_BYPASS="false"; + defparam pll.CLKOUT_DLY_STEP=0; + defparam pll.CLKOUT_FT_DIR=1'b1; + defparam pll.DUTYDA_SEL="1000"; + defparam pll.DYN_DA_EN="false"; + defparam pll.DYN_FBDIV_SEL="false"; + defparam pll.DYN_IDIV_SEL="false"; + defparam pll.DYN_ODIV_SEL="false"; + defparam pll.DYN_SDIV_SEL=10; + defparam pll.PSDA_SEL="0000"; + + assign LCD_CLK = pixel_clk; + + reg [15:0] pixel_count; + reg [15:0] line_count; + + /* 480x272 4.3" LCD with SC7283 driver, pixel freq = 9MHz */ + localparam VBackPorch = 16'd12; + localparam VPulse = 16'd4; + localparam HightPixel = 16'd272; + localparam VFrontPorch= 16'd8; + + localparam HBackPorch = 16'd43; + localparam HPulse = 16'd4; + localparam WidthPixel = 16'd480; + localparam HFrontPorch= 16'd8; + + + localparam PixelForHS = WidthPixel + HBackPorch + HFrontPorch; + localparam LineForVS = HightPixel + VBackPorch + VFrontPorch; + + always @(posedge pixel_clk or negedge rst)begin + if (!rst) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else if (pixel_count == PixelForHS) begin + pixel_count <= 16'b0; + line_count <= line_count + 1'b1; + end + else if (line_count == LineForVS) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else begin + pixel_count <= pixel_count + 1'b1; + end + end + + + assign LCD_HYNC = ((pixel_count >= HPulse) && (pixel_count <= (PixelForHS - HFrontPorch))) ? 1'b0 : 1'b1; + assign LCD_SYNC = (((line_count >= VPulse) && (line_count <= (LineForVS - 0)))) ? 1'b0 : 1'b1; + + assign LCD_DEN = ((pixel_count >= HBackPorch)&& + (pixel_count <= PixelForHS-HFrontPorch) && + (line_count >= VBackPorch) && + (line_count <= LineForVS-VFrontPorch-1)) ? 1'b1 : 1'b0; + + wire [7:0] dout; + reg [11:0] addr; + + image_rom image( + .clk(pixel_clk), + .reset(!rst), + .ad(addr), + .data(dout) + ); + +`define START_X 16'd160 +`define STOP_X (`START_X + 16'd256) +`define START_Y 16'd18 +`define STOP_Y (`START_Y + 16'd256) + + wire [7:0] vmem_start_col; + wire [7:0] vmem_start_row; + assign vmem_start_col = pixel_count - `START_X; + assign vmem_start_row = line_count - `START_Y; + + always @(negedge pixel_clk) begin + addr = {vmem_start_row[7:2], vmem_start_col[7:2]}; + end + + wire is_out_x = pixel_count < `START_X || pixel_count >= `STOP_X; + wire is_out_y = line_count < `START_Y || line_count >= `STOP_Y; + + reg [15:0] color; + always @(negedge pixel_clk) begin + if (is_out_x || is_out_y) begin + color = line_count + pixel_count; + end else begin + color = {dout[4:0], dout[5:0], dout[4:0]}; + end + end + + assign LCD_R = color[4:0]; + assign LCD_G = color[10:5]; + assign LCD_B = color[15:11]; + +endmodule + diff --git a/examples/himbaechel/pROMX9-image-rom.v b/examples/himbaechel/pROMX9-image-rom.v new file mode 100644 index 00000000..713e9ce6 --- /dev/null +++ b/examples/himbaechel/pROMX9-image-rom.v @@ -0,0 +1,44 @@ +`default_nettype none +module image_rom( + input wire clk, + input wire reset, + input wire [11:0] ad, + output wire [8:0] data +); + + wire gnd, vcc; + assign gnd = 1'b0; + assign vcc = 1'b1; + + wire [8:0] dummy_w [1:0]; + wire [8:0] data_w [1:0]; + assign data = data_w[ad[11]]; + + pROMX9 rom2( + .AD({ad[10:0], gnd, gnd, gnd}), + .DO({dummy_w[0], data_w[1]}), + .CLK(clk), + .OCE(vcc), + .CE(vcc), + .RESET(reset) + ); + defparam rom2.READ_MODE = 1'b1; + defparam rom2.BIT_WIDTH = 9; + defparam rom2.RESET_MODE = "SYNC"; +`include "img-rom2.vh" + + pROMX9 rom3( + .AD({ad[10:0], gnd, gnd, gnd}), + .DO({dummy_w[1], data_w[0]}), + .CLK(clk), + .OCE(vcc), + .CE(vcc), + .RESET(reset) + ); + defparam rom3.READ_MODE = 1'b1; + defparam rom3.BIT_WIDTH = 9; + defparam rom3.RESET_MODE = "SYNC"; +`include "img-rom3.vh" + +endmodule + diff --git a/examples/himbaechel/pROMX9-video-ram.v b/examples/himbaechel/pROMX9-video-ram.v new file mode 120000 index 00000000..9d5b4013 --- /dev/null +++ b/examples/himbaechel/pROMX9-video-ram.v @@ -0,0 +1 @@ +pROM-video-ram.v \ No newline at end of file diff --git a/examples/himbaechel/pROMX9.v b/examples/himbaechel/pROMX9.v new file mode 100644 index 00000000..151433bf --- /dev/null +++ b/examples/himbaechel/pROMX9.v @@ -0,0 +1,146 @@ +`default_nettype none +(* top *) +module top +( + input wire rst_i, + input wire clk, + + output wire LCD_CLK, + output wire LCD_HYNC, + output wire LCD_SYNC, + output wire LCD_DEN, + output wire [4:0] LCD_R, + output wire [5:0] LCD_G, + output wire [4:0] LCD_B +); + + wire rst = rst_i ^ `INV_BTN; + wire pixel_clk; + wire gnd; + assign gnd = 1'b0; + + rPLL pll( + .CLKOUT(pixel_clk), // 9MHz + .CLKIN(clk), + .CLKFB(gnd), + .RESET(!rst), + .RESET_P(!rst), + .FBDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .IDSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .ODSEL({gnd, gnd, gnd, gnd, gnd, gnd}), + .DUTYDA({gnd, gnd, gnd, gnd}), + .PSDA({gnd, gnd, gnd, gnd}), + .FDLY({gnd, gnd, gnd, gnd}) + ); + defparam pll.DEVICE = `PLL_DEVICE; + defparam pll.FCLKIN = `PLL_FCLKIN; + defparam pll.FBDIV_SEL = `PLL_FBDIV_SEL_LCD; + defparam pll.IDIV_SEL = `PLL_IDIV_SEL_LCD; + defparam pll.ODIV_SEL = `PLL_ODIV_SEL; + defparam pll.CLKFB_SEL="internal"; + defparam pll.CLKOUTD3_SRC="CLKOUT"; + defparam pll.CLKOUTD_BYPASS="false"; + defparam pll.CLKOUTD_SRC="CLKOUT"; + defparam pll.CLKOUTP_BYPASS="false"; + defparam pll.CLKOUTP_DLY_STEP=0; + defparam pll.CLKOUTP_FT_DIR=1'b1; + defparam pll.CLKOUT_BYPASS="false"; + defparam pll.CLKOUT_DLY_STEP=0; + defparam pll.CLKOUT_FT_DIR=1'b1; + defparam pll.DUTYDA_SEL="1000"; + defparam pll.DYN_DA_EN="false"; + defparam pll.DYN_FBDIV_SEL="false"; + defparam pll.DYN_IDIV_SEL="false"; + defparam pll.DYN_ODIV_SEL="false"; + defparam pll.DYN_SDIV_SEL=10; + defparam pll.PSDA_SEL="0000"; + + assign LCD_CLK = pixel_clk; + + reg [15:0] pixel_count; + reg [15:0] line_count; + + /* 480x272 4.3" LCD with SC7283 driver, pixel freq = 9MHz */ + localparam VBackPorch = 16'd12; + localparam VPulse = 16'd4; + localparam HightPixel = 16'd272; + localparam VFrontPorch= 16'd8; + + localparam HBackPorch = 16'd43; + localparam HPulse = 16'd4; + localparam WidthPixel = 16'd480; + localparam HFrontPorch= 16'd8; + + + localparam PixelForHS = WidthPixel + HBackPorch + HFrontPorch; + localparam LineForVS = HightPixel + VBackPorch + VFrontPorch; + + always @(posedge pixel_clk or negedge rst)begin + if (!rst) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else if (pixel_count == PixelForHS) begin + pixel_count <= 16'b0; + line_count <= line_count + 1'b1; + end + else if (line_count == LineForVS) begin + line_count <= 16'b0; + pixel_count <= 16'b0; + end + else begin + pixel_count <= pixel_count + 1'b1; + end + end + + + assign LCD_HYNC = ((pixel_count >= HPulse) && (pixel_count <= (PixelForHS - HFrontPorch))) ? 1'b0 : 1'b1; + assign LCD_SYNC = (((line_count >= VPulse) && (line_count <= (LineForVS - 0)))) ? 1'b0 : 1'b1; + + assign LCD_DEN = ((pixel_count >= HBackPorch)&& + (pixel_count <= PixelForHS-HFrontPorch) && + (line_count >= VBackPorch) && + (line_count <= LineForVS-VFrontPorch-1)) ? 1'b1 : 1'b0; + + wire [8:0] dout; + reg [11:0] addr; + + image_rom image( + .clk(pixel_clk), + .reset(!rst), + .ad(addr), + .data(dout) + ); + +`define START_X 16'd160 +`define STOP_X (`START_X + 16'd256) +`define START_Y 16'd18 +`define STOP_Y (`START_Y + 16'd256) + + wire [7:0] vmem_start_col; + wire [7:0] vmem_start_row; + assign vmem_start_col = pixel_count - `START_X; + assign vmem_start_row = line_count - `START_Y; + + always @(negedge pixel_clk) begin + addr = {vmem_start_row[7:2], vmem_start_col[7:2]}; + end + + wire is_out_x = pixel_count < `START_X || pixel_count >= `STOP_X; + wire is_out_y = line_count < `START_Y || line_count >= `STOP_Y; + + reg [15:0] color; + always @(negedge pixel_clk) begin + if (is_out_x || is_out_y) begin + color = line_count + pixel_count; + end else begin + color = {dout[8:4], dout[8:3], dout[8:4]}; + end + end + + assign LCD_R = color[4:0]; + assign LCD_G = color[10:5]; + assign LCD_B = color[15:11]; + +endmodule + diff --git a/examples/himbaechel/szfpga.cst b/examples/himbaechel/szfpga.cst index a55e3f9d..493f55c2 100644 --- a/examples/himbaechel/szfpga.cst +++ b/examples/himbaechel/szfpga.cst @@ -42,3 +42,28 @@ IO_LOC "elvds_n" 45; // true LVDS pins IO_LOC "tlvds_p" 42; IO_LOC "tlvds_n" 43; + +// RGB LCD +IO_LOC "LCD_CLK" 110; +IO_LOC "LCD_DEN" 111; +IO_LOC "LCD_HYNC" 112; +IO_LOC "LCD_SYNC" 113; +IO_LOC "LCD_B[4]" 114; +IO_LOC "LCD_B[3]" 115; +IO_LOC "LCD_B[2]" 116; +IO_LOC "LCD_B[1]" 117; +IO_LOC "LCD_B[0]" 118; +IO_LOC "LCD_G[5]" 119; +IO_LOC "LCD_G[4]" 120; +IO_LOC "LCD_G[3]" 121; +IO_LOC "LCD_G[2]" 122; +IO_LOC "LCD_G[1]" 123; +IO_LOC "LCD_G[0]" 124; +IO_LOC "LCD_R[4]" 125; +IO_LOC "LCD_R[3]" 126; +IO_LOC "LCD_R[2]" 128; +IO_LOC "LCD_R[1]" 129; +IO_LOC "LCD_R[0]" 130; + +IO_LOC "LCD_XR" 131; +IO_LOC "LCD_XL" 132; diff --git a/examples/himbaechel/tangnano1k.cst b/examples/himbaechel/tangnano1k.cst index ec3263f3..2de2b913 100644 --- a/examples/himbaechel/tangnano1k.cst +++ b/examples/himbaechel/tangnano1k.cst @@ -6,9 +6,9 @@ IO_LOC "led[2]" 11; IO_PORT "led[2]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8; -IO_LOC "rst_i" 13; +IO_LOC "rst_i" 44; IO_PORT "rst_i" IO_TYPE=LVCMOS33 PULL_MODE=UP; -IO_LOC "key_i" 44; +IO_LOC "key_i" 13; IO_PORT "key_i" IO_TYPE=LVCMOS33 PULL_MODE=UP; IO_LOC "clk" 47; IO_PORT "clk" IO_TYPE=LVCMOS33;