summaryrefslogtreecommitdiff
path: root/hdl
diff options
context:
space:
mode:
Diffstat (limited to 'hdl')
-rw-r--r--hdl/core/control.py112
-rw-r--r--hdl/core/machine_code.csv96
2 files changed, 138 insertions, 70 deletions
diff --git a/hdl/core/control.py b/hdl/core/control.py
index 855cd3b..d858812 100644
--- a/hdl/core/control.py
+++ b/hdl/core/control.py
@@ -11,7 +11,7 @@ from hdl.config import MACHINE_CODE_CSV
import csv
MAX_INSTR = 2**8 # do not change this, this is not configurable
-CL_NAMES = ['mode']
+CL_NAMES = ['mode', 'valid_op', 'wb_en', 'alu_op', 'is_imm', 'jump_en', 'mem_wr_en', 'mem_rd_en', 'mem_rw_word']
class Control_LUT(Elaboratable):
def __init__(self, csv_file, cl_names, **kargs): # cl_names is a list of control line in order of msb to lsb
@@ -19,27 +19,79 @@ class Control_LUT(Elaboratable):
self.cl_names = cl_names
self.sim = kargs.get("sim", False)
+ def elaborate(self, platform=None):
+ pass
+ #TODO: implment this to create signals with the same names as the control lines specified
+
def create_lut(self):
- self.csv_raw = self._read_csv(self.csv_file)
- self.csv_parsed = self._parse_csv(self.csv_raw)
- self.mem_init = self._create_mem_init(self.csv_parsed)
+ csv_raw = self._read_csv(self.csv_file)
+ control_list = self._parse_csv(csv_raw)
+ mem_width, slice_mapping = self._get_slice_mapping(control_list)
+
+ print('debug')
+ print(CL_NAMES)
+ print(mem_width, slice_mapping)
+ print(control_list[10])
+ print(self._create_entry(control_list[10]['data'], mem_width, slice_mapping))
- self.mem = Memory(width=len(self.cl_names) + 1, depth=MAX_INSTR, init=self.mem_init, simulate=self.sim) # one extra bit for valid opcode
+ # self.mem_init = self._create_mem_init(self.csv_parsed)
+ # self.mem = Memory(width=len(self.cl_names) + 1, depth=MAX_INSTR, init=self.mem_init, simulate=self.sim) # one extra bit for valid opcode
# read csv file and return a list of dictionaries
def _read_csv(self, csv_file):
- csv_raw = []
with open(csv_file, 'r') as f:
reader = csv.DictReader(f)
return list(reader)
-
+
+ def _get_slice_mapping(self, control_list):
- def _list_to_one_hot(self, lst):
- tmp = 0
- for i in range(len(lst)):
- tmp |= (lst[i] << i)
+ # helper function to count the number of bits in a number
+ def count_bits(num:int):
+ return len(bin(num)[2:]) # remove the '0b' prefix
+
+ # find the max bit length of the control lines per entry
+ max_width_list = [count_bits(cl) for cl in control_list[0]['data']]
+ for entry in control_list:
+ for i, cl in enumerate(entry['data']):
+ max_width_list[i] = max(max_width_list[i], count_bits(cl))
+
+ # calculate how many bits for each entry
+ mem_width = sum(max_width_list)
+ slice_mapping = []
+ accum = 0
+
+ # generate the slice mapping
+ for i, cl in enumerate(max_width_list):
+ slice_mapping.append(slice(accum, accum + max_width_list[i]))
+ accum += max_width_list[i]
+
+ return mem_width, slice_mapping
+
- return tmp
+ def _create_entry(self, control, mem_width, slice_mapping):
+
+ # check that the slices map to the correct number of bits
+ assert(slice_mapping[-1].stop == mem_width), 'slice mapping is not continuous, this is an internal error'
+
+ def bin_stripped(num):
+ return bin(num)[2:]
+
+ def pad_zero(num_str, width):
+ return '0' * (width - len(num_str)) + num_str
+
+ # create the entry with all zeros
+ entry_str_list = ['0'] * mem_width
+
+ # fill in the control lines, lsb left, msb right
+ for (cl, s) in zip(control, slice_mapping):
+ entry_str_list[s.start:s.stop] = list(reversed(list(pad_zero(bin_stripped(cl), s.stop - s.start)))) # signals read from left to right, so reverse the string
+
+ # conversion to int requires lsb right, msb left
+ entry_str = ''.join(reversed(entry_str_list))
+
+ # convert to int
+ entry = int('0b' + entry_str, 2)
+ return entry
def _parse_csv(self, csv_raw):
csv_parsed = []
@@ -50,12 +102,19 @@ class Control_LUT(Elaboratable):
tmp['data'] = []
for cl in self.cl_names:
- tmp['data'].append(bool(int(row[cl]))) # needs to be converted to int first because boolof a string is true
+ try:
+ tmp['data'].append(int(row[cl]))
+ except KeyError:
+ print(f'control line "{cl}" not found in csv file')
+ raise
csv_parsed.append(tmp)
return csv_parsed
+
+ def _alloc_mem(self, csv_parsed):
+ pass
- def _create_mem_init(self, csv_parsed):
+ def _create_init(self, csv_parsed):
mem_init = []
for i in range(MAX_INSTR):
@@ -67,7 +126,6 @@ class Control_LUT(Elaboratable):
for cl in row['data']:
mem_init[row['opcode']] = cl
- mem_init[row['opcode']] = (mem_init[row['opcode']] << 1) | 0x1 # set the valid opcode bit
return mem_init
@@ -80,13 +138,22 @@ class Control(Elaboratable):
self.alu_op = Signal(e2s(AluOpCodes))
self.jump_ctl_op = Signal(e2s(JumpOpCodes))
- # register control out
- self.wr_en = Signal(1)
- self.stall = Signal(1)
- self.int_sig = Signal(1)
- self.iret = Signal(1)
- self.call = Signal(1)
- self.jump = Signal(1)
+ # syncronous control signals
+ self.valid_op = Signal()
+ self.wb_en = Signal()
+ self.alu_op = Signal(e2s(AluOpCodes))
+ self.is_imm = Signal()
+ self.jump_en = Signal()
+ self.mem_wr_en = Signal()
+ self.mem_rd_en = Signal()
+ self.mem_rw_word = Signal()
+
+
+ self.stall = Signal()
+ self.int_sig = Signal()
+ self.iret = Signal()
+ self.call = Signal()
+ self.jump = Signal()
# register control in
self.int_en = Signal(1)
@@ -123,7 +190,6 @@ class Control(Elaboratable):
def test_control_mem_init():
lut = Control_LUT(MACHINE_CODE_CSV, CL_NAMES, sim=True)
lut.create_lut()
- print(lut.mem_init)
if __name__ == '__main__':
test_control_mem_init()
diff --git a/hdl/core/machine_code.csv b/hdl/core/machine_code.csv
index 96e73d5..d1799aa 100644
--- a/hdl/core/machine_code.csv
+++ b/hdl/core/machine_code.csv
@@ -1,47 +1,49 @@
-name,type,opcode,mode,description,notes
-ADD,R,1,1,RD = RS1 + RS2,
-ADDC,R,2,1,RD = RS1 + RS2 + FLG[0],
-SUB,R,3,1,RD = RS1 - RS2,
-SUBC,R,4,1,RD = RS1 - RS2 - FLG[0],
-XOR,R,5,1,RD = RS1 ^ RS2,
-OR,R,6,1,RD = RS1 | RS2,
-AND,R,7,1,RD = RS1 & RS2,
-LSL,R,8,1,RD = RS1 << RS2 (logical),
-LSR,R,9,1,RD = RS1 >> RS2 (logical),
-ASR,R,10,1,RD = RS1 >> RS2,
-MULL,R,11,1,RD = (RS1 * RS2) & 0xFFFFFFFF,
-MULH,R,12,1,RD = (RS1 * RS2) >> 32,
-MULLU,R,13,1,RD = RS1 * RS2 & 0xFFFFFFFF (unsigned),
-MULHU,R,14,1,RD = (RS1 * RS2) >> 32 (unsigned),
-DIV,R,15,1,RD = RS1 / RS2,not implemented yet
-DIVU,R,16,1,RD = RS1 / RS2 (unsigned),not implemented yet
-LDW,R,17,1,RD = MEM[RS1 + offset],
-LDWR,R,18,1,RD = MEM[RS1 + RS2],
-STW,R,19,1,MEM[RS1 + offset] = RS2,
-LDB,R,20,1,RD = MEM[RS1 + offset] & 0xFF,
-LDBR,R,21,1,RD = MEM[RS1 + RS2] & 0xFF,
-STB,R,22,1,MEM[RS1 + offset] = RS2 & 0xFF,
-ADDI,I,64,1,RD = RS + IMM,
-ADDIC,I,65,1,RD = RS + IMM + FLG[0],
-SUBI,I,66,1,RD = RS - IMM,
-SUBIC,I,67,1,RD = RS - IMM - FLG[0],
-XORI,I,68,1,RD = RS ^ IMM,
-ORI,I,69,1,RD = RS | IMM,
-ANDI,I,70,1,RD = RS & IMM,
-LSLI,I,71,1,RD = RS << IMM (logical),
-LSRI,I,72,1,RD = RS >> IMM (logical),
-ASRI,I,73,1,RD = RS >> IMM,
-MULIL,I,74,1,RD = (RS * IMM) & 0xFFFFFFFF,
-MULIH,I,75,1,RD = (RS * IMM) >> 32,
-MULIU,I,76,1,RD = (RS * IMM) & 0xFFFFFFFF (unsigned),
-MULIUH,I,77,1,RD = (RS * IMM) >> 32 (unsigned),
-DIVI,I,78,1,RD = RS / IMM,not implemented yet
-DIVUI,I,79,1,RD = RS / IMM (unsigned),not implemented yet
-JMP,J,128,1,op depends on machine code,
-JMPI,J,129,1,op depends on machine code,
-NOP,C,0,1,Do nothing -> opcode = ZERO ,
-CALL,C,160,1,CS0=IP; IP=CS0,
-RET,C,161,1,"IP = CS0, this is implemented using jmp or call instruction",
-SCALL,C,162,1,CS0=IP; CS1=SP; CS2=FLG; IP=IDT[6]; SP=CS1; FLG[16]=0; FLG[17]=0;,
-INT,C,192,0,CS0=IP; CS1=SP; CS2=FLG; IP=IDT[IMM]; SP=CS1; FLG[16]=0; FLG[17]=0;,
-IRET,C,193,0,IP=CS0; SP=CS1; FLG=CS2;, \ No newline at end of file
+name,type,opcode,mode,description,notes,valid_op,wb_en,alu_op,is_imm,jump_en,mem_wr_en,mem_rd_en,mem_rw_word
+ADD,R,1,1,RD = RS1 + RS2,,1,1,0,0,0,0,0,0
+ADDC,R,2,1,RD = RS1 + RS2 + FLG[0],,1,1,1,0,0,0,0,0
+SUB,R,3,1,RD = RS1 - RS2,,1,1,2,0,0,0,0,0
+SUBC,R,4,1,RD = RS1 - RS2 - FLG[0],,1,1,3,0,0,0,0,0
+XOR,R,5,1,RD = RS1 ^ RS2,,1,1,6,0,0,0,0,0
+OR,R,6,1,RD = RS1 | RS2,,1,1,5,0,0,0,0,0
+AND,R,7,1,RD = RS1 & RS2,,1,1,4,0,0,0,0,0
+NOR,R,8,1,RD = ~(RS1 | RS2),,1,1,7,0,0,0,0,0
+LSL,R,9,1,RD = RS1 << RS2 (logical),,1,1,8,0,0,0,0,0
+LSR,R,10,1,RD = RS1 >> RS2 (logical),,1,1,9,0,0,0,0,0
+ASR,R,11,1,RD = RS1 >> RS2,,1,1,10,0,0,0,0,0
+MULL,R,12,1,RD = (RS1 * RS2) & 0xFFFFFFFF,,1,1,13,0,0,0,0,0
+MULH,R,13,1,RD = (RS1 * RS2) >> 32,,1,1,14,0,0,0,0,0
+MULLU,R,14,1,RD = RS1 * RS2 & 0xFFFFFFFF (unsigned),,1,1,11,0,0,0,0,0
+MULHU,R,15,1,RD = (RS1 * RS2) >> 32 (unsigned),,1,1,12,0,0,0,0,0
+DIV,R,16,1,RD = RS1 / RS2,not implemented yet,0,0,0,0,0,0,0,0
+DIVU,R,17,1,RD = RS1 / RS2 (unsigned),not implemented yet,0,0,0,0,0,0,0,0
+LDW,R,18,1,RD = MEM[RS1 + offset],,1,1,0,0,0,0,1,1
+LDWR,R,19,1,RD = MEM[RS1 + RS2],,1,1,0,0,0,0,1,1
+STW,R,20,1,MEM[RS1 + offset] = RS2,,1,0,0,0,0,1,0,1
+LDB,R,21,1,RD = MEM[RS1 + offset] & 0xFF,,1,1,0,0,0,0,1,0
+LDBR,R,22,1,RD = MEM[RS1 + RS2] & 0xFF,,1,1,0,0,0,0,1,0
+STB,R,23,1,MEM[RS1 + offset] = RS2 & 0xFF,,1,0,0,0,0,1,0,0
+ADDI,I,64,1,RD = RS + IMM,,1,1,0,1,0,0,0,0
+ADDIC,I,65,1,RD = RS + IMM + FLG[0],,1,1,1,1,0,0,0,0
+SUBI,I,66,1,RD = RS - IMM,,1,1,2,1,0,0,0,0
+SUBIC,I,67,1,RD = RS - IMM - FLG[0],,1,1,3,1,0,0,0,0
+XORI,I,68,1,RD = RS ^ IMM,,1,1,6,1,0,0,0,0
+ORI,I,69,1,RD = RS | IMM,,1,1,5,1,0,0,0,0
+ANDI,I,70,1,RD = RS & IMM,,1,1,4,1,0,0,0,0
+NORI,I,71,1,RD = ~(RS1 | IMM),,1,1,7,1,0,0,0,0
+LSLI,I,72,1,RD = RS << IMM (logical),,1,1,8,1,0,0,0,0
+LSRI,I,73,1,RD = RS >> IMM (logical),,1,1,9,1,0,0,0,0
+ASRI,I,74,1,RD = RS >> IMM,,1,1,10,1,0,0,0,0
+MULIL,I,75,1,RD = (RS * IMM) & 0xFFFFFFFF,,1,1,13,1,0,0,0,0
+MULIH,I,76,1,RD = (RS * IMM) >> 32,,1,1,14,1,0,0,0,0
+MULIUL,I,77,1,RD = (RS * IMM) & 0xFFFFFFFF (unsigned),,1,1,11,1,0,0,0,0
+MULIUH,I,78,1,RD = (RS * IMM) >> 32 (unsigned),,1,1,12,1,0,0,0,0
+DIVI,I,79,1,RD = RS / IMM,not implemented yet,0,0,0,1,0,0,0,0
+DIVUI,I,80,1,RD = RS / IMM (unsigned),not implemented yet,0,0,0,1,0,0,0,0
+JMP,J,128,1,op depends on machine code,,1,0,0,0,1,0,0,0
+JMPI,J,129,1,op depends on machine code,,1,0,0,1,1,0,0,0
+NOP,C,0,1,Do nothing -> opcode = ZERO ,,1,0,0,0,0,0,0,0
+CALL,C,160,1,CS0=IP; IP=CS0,,1,0,0,0,0,0,0,0
+RET,C,161,1,"IP = CS0, this is implemented using jmp or call instruction",,1,0,0,0,0,0,0,0
+SCALL,C,162,1,CS0=IP; CS1=SP; CS2=FLG; IP=IDT[6]; SP=CS1; FLG[16]=0; FLG[17]=0;,,1,0,0,0,0,0,0,0
+INT,C,192,0,CS0=IP; CS1=SP; CS2=FLG; IP=IDT[IMM]; SP=CS1; FLG[16]=0; FLG[17]=0;,,1,0,0,0,0,0,0,0
+IRET,C,193,0,IP=CS0; SP=CS1; FLG=CS2;,,1,0,0,0,0,0,0,0