summaryrefslogtreecommitdiff
path: root/hdl
diff options
context:
space:
mode:
Diffstat (limited to 'hdl')
-rw-r--r--hdl/config.py1
-rw-r--r--hdl/core/control.py93
-rw-r--r--hdl/core/machine_code.csv93
3 files changed, 127 insertions, 60 deletions
diff --git a/hdl/config.py b/hdl/config.py
index 0ff2bc0..7bccd29 100644
--- a/hdl/config.py
+++ b/hdl/config.py
@@ -7,5 +7,6 @@ VERILOG_DIR = os.path.join(ROOT_DIR, 'gen_verilog')
CXXRTL_DIR = os.path.join(ROOT_DIR, 'gen_cxxrtl')
RTLIL_DIR = os.path.join(ROOT_DIR, 'gen_rtlil')
VCD_DIR = os.path.join(ROOT_DIR, 'gen_vcd')
+MACHINE_CODE_CSV = os.path.join(ROOT_DIR, 'core', 'machine_code.csv')
NUM_RAND_TESTS = 100 \ No newline at end of file
diff --git a/hdl/core/control.py b/hdl/core/control.py
index ffea409..855cd3b 100644
--- a/hdl/core/control.py
+++ b/hdl/core/control.py
@@ -4,9 +4,72 @@ from enum import Enum, unique
from hdl.utils import *
from hdl.lib.in_out_buff import InOutBuff # used for timing analysis
-
from hdl.core.alu import AluOpCodes
from hdl.core.jump_ctl import JumpOpCodes
+from hdl.config import MACHINE_CODE_CSV
+
+import csv
+
+MAX_INSTR = 2**8 # do not change this, this is not configurable
+CL_NAMES = ['mode']
+
+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
+ self.csv_file = csv_file
+ self.cl_names = cl_names
+ self.sim = kargs.get("sim", False)
+
+ 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)
+
+ 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 _list_to_one_hot(self, lst):
+ tmp = 0
+ for i in range(len(lst)):
+ tmp |= (lst[i] << i)
+
+ return tmp
+
+ def _parse_csv(self, csv_raw):
+ csv_parsed = []
+
+ for row in csv_raw:
+ tmp = {}
+ tmp['opcode'] = int(row['opcode'])
+ 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
+
+ csv_parsed.append(tmp)
+ return csv_parsed
+
+ def _create_mem_init(self, csv_parsed):
+ mem_init = []
+
+ for i in range(MAX_INSTR):
+ mem_init.append(0) # init to 0, this sets all op codes to invalid
+
+ for row in csv_parsed:
+ assert(0 <= row['opcode'] < MAX_INSTR), "opcode out of range"
+ assert((mem_init[row['opcode']] & 0x1) != 1), 'duplicate opcode, check the .csv file'
+
+ 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
class Control(Elaboratable):
@@ -33,7 +96,7 @@ class Control(Elaboratable):
ports_out = []
self.ports = {'in': ports_in, 'out': ports_out}
- self.sim = kargs["sim"] if "sim" in kargs else False
+ self.sim = kargs.get("sim", False)
def elaborate(self, platform=None):
m = Module()
@@ -49,16 +112,20 @@ class Control(Elaboratable):
# test addition
-def test_hdl():
- dut = Control(sim=True)
- def proc():
- yield from step #step clock
- yield Settle() #needed if for combinatorial logic
- yield dut.something #read value
- sim(dut, proc)
-
-
+# def test_hdl():
+# dut = Control(sim=True)
+# def proc():
+# yield from step #step clock
+# yield Settle() #needed if for combinatorial logic
+# yield dut.something #read value
+# sim(dut, proc)
+
+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__':
- hdl = InOutBuff(Control())
- cmd(hdl)
+ test_control_mem_init()
+ # hdl = InOutBuff(Control())
+ # cmd(hdl)
diff --git a/hdl/core/machine_code.csv b/hdl/core/machine_code.csv
index 1d4c383..96e73d5 100644
--- a/hdl/core/machine_code.csv
+++ b/hdl/core/machine_code.csv
@@ -1,48 +1,47 @@
name,type,opcode,mode,description,notes
-ADD,R,1,u,RD = RS1 + RS2,
-ADDC,R,2,u,RD = RS1 + RS2 + FLG[0],
-SUB,R,3,u,RD = RS1 - RS2,
-SUBC,R,4,u,RD = RS1 - RS2 - FLG[0],
-XOR,R,5,u,RD = RS1 ^ RS2,
-OR,R,6,u,RD = RS1 | RS2,
-AND,R,7,u,RD = RS1 & RS2,
-LSL,R,8,u,RD = RS1 << RS2 (logical),
-LSR,R,9,u,RD = RS1 >> RS2 (logical),
-ASR,R,10,u,RD = RS1 >> RS2,
-MULL,R,11,u,RD = (RS1 * RS2) & 0xFFFFFFFF,
-MULH,R,12,u,RD = (RS1 * RS2) >> 32,
-MULLU,R,13,u,RD = RS1 * RS2 & 0xFFFFFFFF (unsigned),
-MULHU,R,14,u,RD = (RS1 * RS2) >> 32 (unsigned),
-DIV,R,15,u,RD = RS1 / RS2,not implemented yet
-DIVU,R,16,u,RD = RS1 / RS2 (unsigned),not implemented yet
-LDW,R,17,u,RD = MEM[RS1 + offset],
-LDWR,R,18,u,RD = MEM[RS1 + RS2],
-STW,R,19,u,MEM[RS1 + offset] = RS2,
-LDB,R,20,u,RD = MEM[RS1 + offset] & 0xFF,
-LDBR,R,21,u,RD = MEM[RS1 + RS2] & 0xFF,
-STB,R,22,u,MEM[RS1 + offset] = RS2 & 0xFF,
-ADDI,I,64,u,RD = RS + IMM,
-ADDIC,I,65,u,RD = RS + IMM + FLG[0],
-SUBI,I,66,u,RD = RS - IMM,
-SUBIC,I,67,u,RD = RS - IMM - FLG[0],
-XORI,I,68,u,RD = RS ^ IMM,
-ORI,I,69,u,RD = RS | IMM,
-ANDI,I,70,u,RD = RS & IMM,
-LSLI,I,71,u,RD = RS << IMM (logical),
-LSRI,I,72,u,RD = RS >> IMM (logical),
-ASRI,I,73,u,RD = RS >> IMM,
-MULIL,I,74,u,RD = (RS * IMM) & 0xFFFFFFFF,
-MULIH,I,75,u,RD = (RS * IMM) >> 32,
-MULIU,I,76,u,RD = (RS * IMM) & 0xFFFFFFFF (unsigned),
-MULIUH,I,77,u,RD = (RS * IMM) >> 32 (unsigned),
-DIVI,I,78,u,RD = RS / IMM,not implemented yet
-DIVUI,I,79,u,RD = RS / IMM (unsigned),not implemented yet
-JMP,J,128,u,op depends on machine code,
-JMPI,J,129,u,op depends on machine code,
-NOP,C,0,u,Do nothing -> opcode = ZERO ,
-CALL,C,160,u,CS0=IP; IP=CS0,
-RET,C,161,u,"IP = CS0, this is implemented using jmp or call instruction",
-SCALL,C,162,u,CS0=IP; CS1=SP; CS2=FLG; IP=IDT[6]; SP=CS1; FLG[16]=0; FLG[17]=0;,
-INT,C,192,s,CS0=IP; CS1=SP; CS2=FLG; IP=IDT[IMM]; SP=CS1; FLG[16]=0; FLG[17]=0;,
-IRET,C,193,s,IP=CS0; SP=CS1; FLG=CS2;,
-,,,,,
+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