Skip to content

Commit

Permalink
add some remapping, harden conv_2_1
Browse files Browse the repository at this point in the history
  • Loading branch information
mbstrange2 committed Jan 6, 2025
1 parent f505df4 commit fd1cba1
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 11 deletions.
154 changes: 152 additions & 2 deletions lake/spec/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -996,14 +996,164 @@ def get_config_int(self):
def get_total_config_size(self):
return self._final_gen.get_config_size()

def gen_bitstream(self, application):
def get_conv_2_1_app(self):

linear_test = {}

length_scale = 32

pw_vec_w = 0
pr_vec_w = 1

pr_raw_idx_vec_w = 0
pw_raw_idx_vec_w = 1
raw_comp_vec_w = LFComparisonOperator.LT.value
raw_scalar_vec_w = 0
raw_constraint_vec_w = (pr_vec_w, pr_raw_idx_vec_w,
pw_vec_w, pw_raw_idx_vec_w, raw_comp_vec_w, raw_scalar_vec_w)

pr_war_idx_vec_w = 0
pw_war_idx_vec_w = 1
war_comp_vec_w = LFComparisonOperator.GT.value
war_scalar_vec_w = 2
war_constraint_vec_w = (pw_vec_w, pw_war_idx_vec_w, pr_vec_w,
pr_war_idx_vec_w, war_comp_vec_w, war_scalar_vec_w)

linear_test[0] = {
'type': Direction.IN,
'name': 'port_w0',
'config': {
'dimensionality': 1,
# 'extents': [16 * length_scale],
'extents': [1024],
'address': {
'strides': [1],
'offset': 0
},
'schedule': {
'strides': [4],
'offset': 4
}
},
'vec_in_config': {
'dimensionality': 2,
'extents': [4, 16 * length_scale],
'address': {
'strides': [1, 4],
'offset': 0
},
'schedule': {
'strides': [1, 4],
'offset': 0
}
},
'vec_out_config': {
'dimensionality': 1,
'extents': [16 * length_scale],
'address': {
'strides': [1],
'offset': 0
},
'schedule': {
'strides': [4],
'offset': 4
}
},
'vec_constraints': [raw_constraint_vec_w, war_constraint_vec_w]
}

pw_vec_r = 0
pr_vec_r = 1

pr_raw_idx_vec_r = 1
pw_raw_idx_vec_r = 0
raw_comp_vec_r = LFComparisonOperator.LT.value
raw_scalar_vec_r = 0
raw_constraint_vec_r = (pr_vec_r, pr_raw_idx_vec_r,
pw_vec_r, pw_raw_idx_vec_r, raw_comp_vec_r, raw_scalar_vec_r)

pr_war_idx_vec_r = 1
pw_war_idx_vec_r = 0
war_comp_vec_r = LFComparisonOperator.GT.value
war_scalar_vec_r = 2
war_constraint_vec_r = (pw_vec_r, pw_war_idx_vec_r, pr_vec_r,
pr_war_idx_vec_r, war_comp_vec_r, war_scalar_vec_r)

linear_test[2] = {
'type': Direction.OUT,
'name': 'port_r0',
'config': {
'dimensionality': 1,
# 'extents': [16 * length_scale],
'extents': [1024],
'address': {
'strides': [1],
'offset': 0
},
'schedule': {
'strides': [4],
'offset': 17
}
},
'vec_in_config': {
'dimensionality': 1,
'extents': [16 * length_scale],
'address': {
'strides': [1],
'offset': 0
},
'schedule': {
'strides': [4],
'offset': 18
}
},
'vec_out_config': {
'dimensionality': 2,
'extents': [4, 16 * length_scale],
'address': {
'strides': [1, 4],
'offset': 0
},
'schedule': {
'strides': [1, 4],
'offset': 19
}
},
'vec_constraints': [raw_constraint_vec_r, war_constraint_vec_r]
}

pw = 0
pr = 2

pr_raw_idx = 0
pw_raw_idx = 0
raw_comp = LFComparisonOperator.LT.value
# raw_scalar = 4
raw_scalar = 64
raw_constraint = (pr, pr_raw_idx, pw, pw_raw_idx, raw_comp, raw_scalar)

pw_war_idx = 0
pr_war_idx = 0
war_comp = LFComparisonOperator.GT.value
war_scalar = 100
war_constraint = (pw, pw_war_idx, pr, pr_war_idx, war_comp, war_scalar)

# Just have read follow write
linear_test['constraints'] = [raw_constraint, war_constraint]

return linear_test

def gen_bitstream(self, application, override=False):
'''Overall flow of the bitstreams is to basically go through each port and map down the information.
There may be other information that needs to go into the configuration, but that could be in the object hierarchy
'''

print("Producing SPEC BITSTREAM with Application:")
print(application)

if override is True:
conv_2_1_app = self.get_conv_2_1_app()
application = conv_2_1_app

# Need to integrate all the bitstream information
# into one single integer/string for the verilog harness
self.clear_configuration()
Expand Down
6 changes: 3 additions & 3 deletions lake/spec/spec_memory_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ def print_name(self):
def get_bitstream(self, config_json, prefix=""):
print("in spec config bitstream...")
print(config_json)
# bs = self.spec.gen_bitstream(config_json)
bs = []
return bs
bs = self.spec.gen_bitstream(config_json, override=True)
bs_full = [('config_memory', bs)]
return bs_full


if __name__ == "__main__":
Expand Down
53 changes: 47 additions & 6 deletions lake/top/memtile_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,11 @@ def get_bitstream(self, config_json):

if 'mode' in config_json:
mode_used = config_json['mode']
# HACK: Replace UB with lakespec if not in mode map (and do it before mode selection so that
# the register is programmed correctly)
if mode_used == 'UB' and 'UB' not in mode_map:
mode_used = 'lakespec'

if self.num_modes > 1:
# Locate the controller in the list...
for idx, ctrl in enumerate(self.controllers):
Expand All @@ -1258,9 +1263,6 @@ def get_bitstream(self, config_json):
config.append(("mode", idx))
break

if mode_used == 'UB' and 'UB' not in mode_map:
mode_used = 'lakespec'

ctrl_to_conf = mode_map[mode_used]
# Have some guard to see if config is in there or not...
if 'config' in config_json:
Expand Down Expand Up @@ -1291,11 +1293,14 @@ def get_bitstream(self, config_json):
map_hi = map_lo + self.allowed_reg_size - 1
else:
map_hi = tmp_hi
assert map_hi - map_lo < self.allowed_reg_size, f"Failed beacuse reg wider than {self.allowed_reg_size} bits"
# This check doesn't make sense anymore - we can handle many-chunk registers that are
# split across many addresses in the config space.
# assert map_hi - map_lo < self.allowed_reg_size, f"Failed beacuse reg wider than {self.allowed_reg_size} bits"
chunk_hi = map_hi // self.allowed_reg_size
chunk_lo = map_lo // self.allowed_reg_size
# Either all within one chunk...
if chunk_hi == chunk_lo:
print("Single-chunk register")
bits_hi = map_hi - chunk_hi * self.allowed_reg_size
bits_lo = map_lo - chunk_lo * self.allowed_reg_size
num_bits = bits_hi - bits_lo + 1
Expand All @@ -1304,20 +1309,56 @@ def get_bitstream(self, config_json):
tmp_val = self.set_bit(tmp_val, z_ + bits_lo, self.get_bit(val_int, z_))
tmp_cfg_space[chunk_lo] = tmp_val
# Or across the boundary...
else:
elif chunk_hi - chunk_lo == 1:
print("Two-chunk register")
bits_hi = map_hi - chunk_hi * self.allowed_reg_size + 1
bits_lo = map_lo - chunk_lo * self.allowed_reg_size
num_bits_lo = self.allowed_reg_size - bits_lo
assert (bits_hi + num_bits_lo) == (map_hi - map_lo + 1)
# Handle low chunk
tmp_val = tmp_cfg_space[chunk_lo]
for z_ in range(num_bits_lo):
tmp_val = self.set_bit(tmp_val, z_ + bits_lo, self.get_bit(val_int, z_))
tmp_cfg_space[chunk_lo] = tmp_val

# Handle high chunk
tmp_val = tmp_cfg_space[chunk_hi]
for z_ in range(bits_hi):
tmp_val = self.set_bit(tmp_val, z_, self.get_bit(val_int, num_bits_lo + z_))
tmp_cfg_space[chunk_hi] = tmp_val
# Multiple boundaries
else:
# I know this is technically repeat code, but it's easier to follow
print("Many-chunk register")
bits_hi = map_hi - chunk_hi * self.allowed_reg_size + 1
bits_lo = map_lo - chunk_lo * self.allowed_reg_size
intermediate_chunks = chunk_hi - chunk_lo - 1
bits_intermed = intermediate_chunks * self.allowed_reg_size
num_bits_lo = self.allowed_reg_size - bits_lo
assert (bits_hi + num_bits_lo + bits_intermed) == (map_hi - map_lo + 1)
# Handle low chunk
tmp_val = tmp_cfg_space[chunk_lo]
for z_ in range(num_bits_lo):
print(f"Get bit at {z_}")
tmp_val = self.set_bit(tmp_val, z_ + bits_lo, self.get_bit(val_int, z_))
tmp_cfg_space[chunk_lo] = tmp_val

# Handle the middle chunks
int_chk = 0
while int_chk < intermediate_chunks:
curr_chunk = chunk_lo + 1 + int_chk
tmp_val = tmp_cfg_space[curr_chunk]
for z_ in range(self.allowed_reg_size):
print(f"Get bit at {(int_chk * self.allowed_reg_size) + num_bits_lo + z_}")
tmp_val = self.set_bit(tmp_val, z_, self.get_bit(val_int, (int_chk * self.allowed_reg_size) + num_bits_lo + z_))
tmp_cfg_space[curr_chunk] = tmp_val
int_chk += 1

# Handle high chunk
tmp_val = tmp_cfg_space[chunk_hi]
for z_ in range(bits_hi):
print(f"Get bit at {bits_intermed + num_bits_lo + z_}")
tmp_val = self.set_bit(tmp_val, z_, self.get_bit(val_int, bits_intermed + num_bits_lo + z_))
tmp_cfg_space[chunk_hi] = tmp_val

for idx in range(self.num_chopped_cfg):
config.append((f"CONFIG_SPACE_{idx}", tmp_cfg_space[idx]))
Expand Down

0 comments on commit fd1cba1

Please sign in to comment.