From 498380308fe45e35439c090a2d16ecf51c546d18 Mon Sep 17 00:00:00 2001 From: jjsuperpower Date: Tue, 24 Jan 2023 22:55:49 -0600 Subject: working on reading control lines from csv --- .vscode/settings.json | 5 +-- hdl/config.py | 1 + hdl/core/control.py | 93 ++++++++++++++++++++++++++++++++++++++++------- hdl/core/machine_code.csv | 93 +++++++++++++++++++++++------------------------ 4 files changed, 128 insertions(+), 64 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 91b67c4..1e794ac 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,8 @@ { "makefile.extensionOutputFolder": "./.vscode", "python.testing.pytestArgs": [ - "hdl" + "." ], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true, - "python.analysis.extraPaths": [ - "./amaranth" - ], } \ No newline at end of file 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 -- cgit v1.2.3