瀏覽代碼

Fixed rom & pc timing and compiler

There was timing issue with ROM and program counter that been fixed by
taking pcn (pc next) value instead of waiting for ff. Also fixed
compiler invalid label address reading with move instruction.
Min 6 年之前
父節點
當前提交
44db81d413
共有 10 個文件被更改,包括 124 次插入92 次删除
  1. 6 0
      .gitignore
  2. 0 56
      src/blocks/instr_mem.sv
  3. 0 18
      src/blocks/instr_mem_wr.sv
  4. 3 0
      src/blocks/rom.sv
  5. 1 1
      src/risc/controller.csv
  6. 2 2
      src/risc/controller.sv
  7. 7 6
      src/risc/datapath.sv
  8. 12 8
      tools/asm_compiler.py
  9. 85 0
      tools/bs_test.asm
  10. 8 1
      tools/risc8asm.py

+ 6 - 0
.gitignore

@@ -10,8 +10,14 @@
 *.log
 *.log
 *.out
 *.out
 *.synctex.gz
 *.synctex.gz
+*.mem
+*.mif
+*.ver
+modelsim.ini
+__pycache__
 msim_transcript
 msim_transcript
 rtl_work/
 rtl_work/
+simulation/
 .idea
 .idea
 .qsys_edit/
 .qsys_edit/
 db/
 db/

+ 0 - 56
src/blocks/instr_mem.sv

@@ -1,56 +0,0 @@
-module instr_rom(addr, instr);
-	parameter FILE = "";	
-	parameter WIDTH=8, LENGTH=256, OUTMUL=2;
-	parameter ADDR_WIDTH = $clog2(LENGTH);
-
-	input  wire [ADDR_WIDTH-1:0]   addr;
-	output reg  [WIDTH*OUTMUL-1:0] instr;
-	
-	initial $display("Instruction ROM %0dx%0dbit, size of %0dB loaded from %s", WIDTH, ADDR_WIDTH, LENGTH*WIDTH/8, FILE);
-	logic [WIDTH-1:0] rom [LENGTH-1:0];
-	initial if(FILE != "") $readmemh(FILE, rom);
-	initial begin
-		 $display("Instruction ROM dump");
-		 for (int i=0; i < LENGTH; i+=32) begin
-			$write("%h:", i);
-			for(int j=0; j<32 && j+i < LENGTH; j++)
-		 		$write(" %h", rom[i+j]);
-			$display(" :%h", i);
-		end
-	end
- 
-	always_comb begin
-		for (int i=0; i<OUTMUL;i++) 
-				instr[WIDTH*i+:WIDTH] = (addr+i >= LENGTH) ? '0 : rom[addr + i];
-	end
-endmodule
-
-`timescale 1ns / 1ns
-module instr_rom_tb;
-	reg [15:0] addr;
-	reg [15:0] instr;
-
-	instr_rom #("../../memory/rom_test.mem", 8, 256, 2, 16) rom0(addr, instr);
-
-	initial begin
-		addr = 'h0000;
-		#10ns;
-		assert(instr == 'h0100);
-		addr = 'h0001;
-		#10ns;
-		assert(instr == 'h0201);
-		addr = 'h0002;
-		#10ns;
-		assert(instr == 'h0302);
-		addr = 'h0003;
-		#10ns;
-		assert(instr == 'h0403);
-		addr = 'h00ff;
-		#10ns;
-		assert(instr == 'h00ff);
-		addr = 'haaff;
-		#10ns;
-		assert(instr == 'h0000);
-	end
-
-endmodule

+ 0 - 18
src/blocks/instr_mem_wr.sv

@@ -1,18 +0,0 @@
-//module instr_rom_wr(clk, addr, instr, wr_en, wr_data);
-module rom(addr, q);
-	parameter PROGRAM="";
-	parameter WIDTH=8, SIZE=1024;
-	parameter ADDR_WIDTH = $clog2(SIZE);
-	
-	//input  reg 	clk, wr_en;
-	//input reg [WIDTH-1:0] wr_data;
-	input  wire [ADDR_WIDTH-1:0]   addr;
-	output  reg  [WIDTH-1:0] q;
-	
-	logic [WIDTH-1:0] rom [ADDR_WIDTH-1:0];
-	initial $readmemh(PROGRAM, rom);
-	//always_ff@(posedge clk) if(wr) rom[addr] <= instr; 	
-
-	always_comb q[WIDTH-1:0] = rom[addr];
-endmodule
-

+ 3 - 0
src/blocks/rom.sv

@@ -136,6 +136,9 @@ module rom (
 		pseudo_rom#({PROGRAM, "_1.mem"}) rom1(addr1, clock, q1);
 		pseudo_rom#({PROGRAM, "_1.mem"}) rom1(addr1, clock, q1);
 		pseudo_rom#({PROGRAM, "_2.mem"}) rom2(addr2, clock, q2);
 		pseudo_rom#({PROGRAM, "_2.mem"}) rom2(addr2, clock, q2);
 		pseudo_rom#({PROGRAM, "_3.mem"}) rom3(addr3, clock, q3);
 		pseudo_rom#({PROGRAM, "_3.mem"}) rom3(addr3, clock, q3);
+		// Currently read address (for debugging)
+		reg [11:0] ff_addr;
+		always_ff@(posedge clock) ff_addr <= address;
 	`endif
 	`endif
 
 
 endmodule
 endmodule

+ 1 - 1
src/risc/controller.csv

@@ -34,7 +34,7 @@
       BZ,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP, PC_NONE 
       BZ,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP, PC_NONE 
     CALL,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      1,         2,SO_MEML ,  ST_SUB,  PC_IMM 
     CALL,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      1,         2,SO_MEML ,  ST_SUB,  PC_IMM 
      RET,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      1,      0,         2,SO_MEML ,  ST_ADD,  PC_MEM 
      RET,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      1,      0,         2,SO_MEML ,  ST_ADD,  PC_MEM 
-    JUMP,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         1,SO_MEML , ST_NONE,  PC_IMM
+    JUMP,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         2,SO_MEML , ST_NONE,  PC_IMM
     RETI,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      1,      0,         2,SO_MEML ,  ST_SUB,  PC_MEM 
     RETI,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      1,      0,         2,SO_MEML ,  ST_SUB,  PC_MEM 
      CLC,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP, PC_NONE 
      CLC,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP, PC_NONE 
     SETC,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP, PC_NONE 
     SETC,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP, PC_NONE 

+ 2 - 2
src/risc/controller.sv

@@ -526,7 +526,7 @@ module controller8(
             cdi.selr    = SR_NONE;
             cdi.selr    = SR_NONE;
             mem_rd      = 0;
             mem_rd      = 0;
             mem_wr      = 1;
             mem_wr      = 1;
-            cdi.isize   = 1;
+            cdi.isize   = 2;
             cdi.selo    = SO_MEML;
             cdi.selo    = SO_MEML;
             cdi.stackop = ST_SUB;
             cdi.stackop = ST_SUB;
             cdi.pcop    = PC_IMM;
             cdi.pcop    = PC_IMM;
@@ -556,7 +556,7 @@ module controller8(
             cdi.selr    = SR_NONE;
             cdi.selr    = SR_NONE;
             mem_rd      = 0;
             mem_rd      = 0;
             mem_wr      = 0;
             mem_wr      = 0;
-            cdi.isize   = 1;
+            cdi.isize   = 3;
             cdi.selo    = SO_MEML;
             cdi.selo    = SO_MEML;
             cdi.stackop = ST_NONE;
             cdi.stackop = ST_NONE;
             cdi.pcop    = PC_IMM;
             cdi.pcop    = PC_IMM;

+ 7 - 6
src/risc/datapath.sv

@@ -63,11 +63,12 @@ module datapath8(
 
 
 	logic bconst; // Use immediate to branch
 	logic bconst; // Use immediate to branch
 	word pc_off; // Program counter offset
 	word pc_off; // Program counter offset
-	reg [15:0] pcn, pca; // Program Counter Previous, to add
+	reg [15:0] pcn, pca, pcx; // Program Counter Previous, to add
 	always_ff@(posedge clk) begin
 	always_ff@(posedge clk) begin
-			if(rst) pc <= 0; 
-			else pc <= pcn;
+			if(rst) pcx <= 0; 
+			else pcx <= pcn;
 	end
 	end
+	assign pc = (rst) ? 0 : pcn;
 	
 	
 	always_comb begin
 	always_comb begin
 		bconst = 0;  // FIXME: temporary
 		bconst = 0;  // FIXME: temporary
@@ -78,11 +79,11 @@ module datapath8(
 			(~cdi.isize[1]&~cdi.isize[0])|(cdi.isize[1]&~cdi.isize[0])
 			(~cdi.isize[1]&~cdi.isize[0])|(cdi.isize[1]&~cdi.isize[0])
 		}; // Adding 1 to 2bit value.
 		}; // Adding 1 to 2bit value.
 		case(cdi.pcop)
 		case(cdi.pcop)
-			PC_NONE: pcn = pc + pc_off;
+			PC_NONE: pcn = pcx + pc_off;
 			PC_MEM : pcn = mem_rd;
 			PC_MEM : pcn = mem_rd;
 			PC_IMM : pcn = {imm[7:0], imm[15:8]};
 			PC_IMM : pcn = {imm[7:0], imm[15:8]};
 			PC_IMM2: pcn = {imm[15:8], imm[23:16]};
 			PC_IMM2: pcn = {imm[15:8], imm[23:16]};
-			default: pcn = pc;
+			default: pcn = pcx;
 		endcase
 		endcase
 		//pca = (bconst) ? {imm[7:0], imm[15:8]} : pc;
 		//pca = (bconst) ? {imm[7:0], imm[15:8]} : pc;
 		//pcn = pca + pc_off;
 		//pcn = pca + pc_off;
@@ -140,7 +141,7 @@ module datapath8(
 
 
 	// COM Write
 	// COM Write
 	assign com_wr = (cdi.selo == SO_COM) ? r1 : '0;
 	assign com_wr = (cdi.selo == SO_COM) ? r1 : '0;
-	assign com_addr = imm[7:0];
+	assign com_addr = (cdi.selo == SO_COM) ? imm[7:0] : '0;
 	//assign com_addr = 8'h06;
 	//assign com_addr = 8'h06;
 	//assign com_wr = pc[7:0];
 	//assign com_wr = pc[7:0];
 
 

+ 12 - 8
tools/asm_compiler.py

@@ -155,10 +155,14 @@ class CompObject:
         self.line_num = line_num
         self.line_num = line_num
         self.code = []
         self.code = []
         self.code_ref = 0
         self.code_ref = 0
-
-    def compile(self):
         self.code = self.instr.compile(self.operands)
         self.code = self.instr.compile(self.operands)
-        return self.code
+
+    def instr_len(self):
+        if hasattr(self.instr, 'get_imm_operands'):
+            o = getattr(self.instr, 'get_imm_operands')
+            return o(self.operands)
+        else:
+            return self.instr.length
 
 
 
 
 class Compiler:
 class Compiler:
@@ -308,7 +312,7 @@ class Compiler:
             label = linespl[0]
             label = linespl[0]
             if label in self.labels:
             if label in self.labels:
                 raise CompilingError(f"Label {label} duplicate")
                 raise CompilingError(f"Label {label} duplicate")
-            self.labels[label] = (self.caddress).to_bytes(self.address_size, self.order)
+            self.labels[label] = self.caddress.to_bytes(self.address_size, self.order)
         if line.startswith('%define'):
         if line.startswith('%define'):
             sp = list(filter(None, line.split(' ', 3)))
             sp = list(filter(None, line.split(' ', 3)))
             if len(sp) != 3:
             if len(sp) != 3:
@@ -339,14 +343,14 @@ class Compiler:
                 co = self.__precompile(line)
                 co = self.__precompile(line)
                 if co is not None:
                 if co is not None:
                     co.line_num = lnum
                     co.line_num = lnum
-                    self.caddress += co.instr.length
+                    self.caddress += co.instr_len()
                     instr.append(co)
                     instr.append(co)
             except CompilingError as e:
             except CompilingError as e:
                 failure = True
                 failure = True
                 print(f"ERROR {file}:{lnum}: {e.message}")
                 print(f"ERROR {file}:{lnum}: {e.message}")
         for co in instr:
         for co in instr:
             try:
             try:
-                binary += co.compile()
+                binary += co.code
             except CompilingError as e:
             except CompilingError as e:
                 failure = True
                 failure = True
                 print(f"ERROR {file}:{co.line_num}: {e.message}")
                 print(f"ERROR {file}:{co.line_num}: {e.message}")
@@ -379,12 +383,12 @@ def convert_to_binary(data):
 
 
 def convert_to_mem(data):
 def convert_to_mem(data):
     x = b''
     x = b''
-    fa = f'0{math.ceil(int(math.log2(len(data)))/4)}x'
+    fa = f'0{math.ceil(math.ceil(math.log2(len(data)))/4)}x'
     a = [format(d, '02x') for d in data]
     a = [format(d, '02x') for d in data]
     for i in range(int(len(a) / 8) + 1):
     for i in range(int(len(a) / 8) + 1):
         y = a[i * 8:(i + 1) * 8]
         y = a[i * 8:(i + 1) * 8]
         if len(y) > 0:
         if len(y) > 0:
-            x += (' '.join(y) + '  // ' + format(i*8, fa) + '\n').encode()
+            x += (' '.join(y) + ' '*((8-len(y))*3) + '  // ' + format((i*8-1)+len(y), fa) + '\n').encode()
     return x
     return x
 
 
 
 

+ 85 - 0
tools/bs_test.asm

@@ -0,0 +1,85 @@
+    global start
+    section .text
+start:
+    mov
+message: db   "Hello Wolrd", 0
+
+
+;CPY $re 0xFF
+;CPY $rb 0x01
+;CPY $ra 'H'
+;SW $ra $re
+;
+;CPY $ra '3'
+;node3:
+;LW $rc $re
+;JEQ $rc $rb node3
+;SW $ra $re
+;
+;CPY $ra 'l'
+;nodeL1:
+;LW $rc $re
+;JEQ $rc $rb nodeL1
+;SW $ra $re
+;
+;nodeL2:
+;LW $rc $re
+;JEQ $rc $rb nodeL2
+;SW $ra $re
+;
+;CPY $ra '0'
+;node0:
+;LW $rc $re
+;JEQ $rc $rb node0
+;SW $ra $re
+;
+;CPY $ra '_'
+;nodeS:
+;LW $rc $re
+;JEQ $rc $rb nodeS
+;SW $ra $re
+;
+;CPY $ra 'P'
+;nodeP:
+;LW $rc $re
+;JEQ $rc $rb nodeP
+;SW $ra $re
+;
+;CPY $ra 'r'
+;nodeR:
+;LW $rc $re
+;JEQ $rc $rb nodeR
+;SW $ra $re
+;
+;CPY $ra '1'
+;node1:
+;LW $rc $re
+;JEQ $rc $rb node1
+;SW $ra $re
+;
+;CPY $ra 'c'
+;nodeC:
+;LW $rc $re
+;JEQ $rc $rb nodeC
+;SW $ra $re
+;
+;CPY $ra 'k'
+;nodeK:
+;LW $rc $re
+;JEQ $rc $rb nodeK
+;SW $ra $re
+;
+;CPY $ra 0x0A
+;nodeLF:
+;LW $rc $re
+;JEQ $rc $rb nodeLF
+;SW $ra $re
+;
+;CPY $ra 0x0D
+;nodeCR:
+;LW $rc $re
+;JEQ $rc $rb nodeCR
+;SW $ra $re
+;
+;stop:
+;JMP stop

+ 8 - 1
tools/risc8asm.py

@@ -13,13 +13,20 @@ asmc.add_reg('r3', 3)
 
 
 
 
 class MoveInstr(compiler.Instruction):
 class MoveInstr(compiler.Instruction):
+    def get_imm_operands(self, operands):
+        try:
+            self.compiler.decode_reg(operands[1])
+            return 1
+        except compiler.CompilingError:
+            return 2
+
     def compile(self, operands):
     def compile(self, operands):
         regs = [0, 0]
         regs = [0, 0]
         imm = []
         imm = []
         regs[0] = self.compiler.decode_reg(operands[0])
         regs[0] = self.compiler.decode_reg(operands[0])
         try:
         try:
             regs[1] = self.compiler.decode_reg(operands[1])
             regs[1] = self.compiler.decode_reg(operands[1])
-            self.imm_operands = 0
+            self.imm_operands = 0   # Assuming this gonna be changed every time
         except compiler.CompilingError:
         except compiler.CompilingError:
             regs[1] = regs[0]
             regs[1] = regs[0]
             self.imm_operands = 1
             self.imm_operands = 1