Parcourir la source

Updates to project and working RISC

Min il y a 5 ans
Parent
commit
d08b734f01
14 fichiers modifiés avec 178 ajouts et 81 suppressions
  1. 1 1
      Makefile
  2. 2 2
      UCL_project_y3.qsf
  3. 15 6
      quartus/pll_clk.v
  4. 18 8
      scripts/update_risc8.tcl
  5. 37 6
      src/blocks/alu.sv
  6. 9 9
      src/blocks/rom.sv
  7. 15 2
      src/const.sv
  8. 5 0
      src/empty.sv
  9. 5 2
      src/project.sv
  10. 1 1
      src/risc/cpu.sv
  11. 2 2
      src/risc/datapath.sv
  12. 56 33
      src/top.sv
  13. 1 1
      tools/interface.py
  14. 11 8
      tools/tests.py

+ 1 - 1
Makefile

@@ -125,7 +125,7 @@ build: $(BUILD_OUT)
 %.text.mif: %.text.o $(BUILD_OUT)
 	$(ASMC) -t mif -f $< .text
 
-memory: $(MEM_BUID)
+memory: $(MEM_BUILD)
 
 flash: $(BUILD_OUT)
 	$(QUARTUS_DIR)/bin/quartus_stp -t ./scripts/update_$(PROCESSOR_LOW).tcl

+ 2 - 2
UCL_project_y3.qsf

@@ -120,7 +120,6 @@ set_global_assignment -name EDA_TEST_BENCH_NAME top_tb -section_id eda_simulatio
 set_global_assignment -name EDA_DESIGN_INSTANCE_NAME NA -section_id top_tb
 set_global_assignment -name EDA_TEST_BENCH_MODULE_NAME top_tb -section_id top_tb
 set_global_assignment -name EDA_TEST_BENCH_FILE src/top.sv -section_id top_tb
-set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
 set_global_assignment -name SYSTEMVERILOG_FILE src/blocks/debug.sv
 set_global_assignment -name SYSTEMVERILOG_FILE src/blocks/rom.sv
 set_global_assignment -name SYSTEMVERILOG_FILE src/project.sv
@@ -137,4 +136,5 @@ set_global_assignment -name QIP_FILE quartus/pll_clk.qip
 set_global_assignment -name SYSTEMVERILOG_FILE src/blocks/alu.sv
 set_global_assignment -name QIP_FILE quartus/risc8_rom.qip
 set_global_assignment -name QIP_FILE quartus/m9k_ram_init.qip
-set_global_assignment -name QIP_FILE quartus/m9k_rom_16.qip
+set_global_assignment -name QIP_FILE quartus/m9k_rom_16.qip
+set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

+ 15 - 6
quartus/pll_clk.v

@@ -42,6 +42,15 @@ module pll_clk (
 	c0,
 	c1,
 	c2);
+	
+	// Default parameters are for 50MHz input,
+	// CLK0 - 100MHz, CLK1 - 1MHz, CLK2 - 32kHz
+	parameter CLK0_MUL = 2;
+	parameter CLK0_DIV = 1;
+	parameter CLK1_MUL = 1;
+	parameter CLK1_DIV = 50;
+	parameter CLK2_MUL = 256;
+	parameter CLK2_DIV = 390625;
 
 	input	  areset;
 	input	  inclk0;
@@ -107,17 +116,17 @@ module pll_clk (
 				.vcounderrange ());
 	defparam
 		altpll_component.bandwidth_type = "AUTO",
-		altpll_component.clk0_divide_by = 1,
+		altpll_component.clk0_divide_by = CLK0_DIV,
 		altpll_component.clk0_duty_cycle = 50,
-		altpll_component.clk0_multiply_by = 2,
+		altpll_component.clk0_multiply_by = CLK0_MUL,
 		altpll_component.clk0_phase_shift = "0",
-		altpll_component.clk1_divide_by = 50,
+		altpll_component.clk1_divide_by = CLK1_DIV,
 		altpll_component.clk1_duty_cycle = 50,
-		altpll_component.clk1_multiply_by = 1,
+		altpll_component.clk1_multiply_by = CLK1_MUL,
 		altpll_component.clk1_phase_shift = "0",
-		altpll_component.clk2_divide_by = 390625,
+		altpll_component.clk2_divide_by = CLK2_DIV,
 		altpll_component.clk2_duty_cycle = 50,
-		altpll_component.clk2_multiply_by = 256,
+		altpll_component.clk2_multiply_by = CLK2_MUL,
 		altpll_component.clk2_phase_shift = "0",
 		altpll_component.compensate_clock = "CLK0",
 		altpll_component.inclk0_input_frequency = 20000,

+ 18 - 8
scripts/update_risc8.tcl

@@ -11,29 +11,39 @@ foreach device_name [get_device_names -hardware_name $usbblaster_name] {
 }
 puts "Device: $test_device";
 begin_memory_edit -hardware_name $hardware_name -device_name $device_name
+start_insystem_source_probe -hardware_name $hardware_name -device_name $device_name
+write_source_data -instance_index 0 -value 1 -value_in_hex
+
+puts "Flashing ram0...";
+set content [exec python ./tools/format_utils.py -w 16 -t uhex -s ./memory/build/risc8.data.o]
+#set content [exec cat ./memory/risc8.data.uhex]
+write_content_to_memory -instance_index 0 -content $content -content_in_hex -start_address 0 -word_count 4096
 
 puts "Flashing rom0...";
-set content [exec cat ./memory/risc8.text_0.uhex]
+set content [exec python ./tools/format_utils.py -w 8 -S 4 -n 0 -t uhex -s ./memory/build/risc8.text.o]
+#set content [exec cat ./memory/risc8.text_0.uhex]
 write_content_to_memory -instance_index 1 -content $content -content_in_hex -start_address 0 -word_count 1024
 
 puts "Flashing rom1...";
-set content [exec cat ./memory/risc8.text_1.uhex]
+set content [exec python ./tools/format_utils.py -w 8 -S 4 -n 1 -t uhex -s ./memory/build/risc8.text.o]
+#set content [exec cat ./memory/risc8.text_1.uhex]
 write_content_to_memory -instance_index 2 -content $content -content_in_hex -start_address 0 -word_count 1024
 
 puts "Flashing rom2...";
-set content [exec cat ./memory/risc8.text_2.uhex]
+set content [exec python ./tools/format_utils.py -w 8 -S 4 -n 2 -t uhex -s ./memory/build/risc8.text.o]
+#set content [exec cat ./memory/risc8.text_2.uhex]
 write_content_to_memory -instance_index 3 -content $content -content_in_hex -start_address 0 -word_count 1024
 
 puts "Flashing rom3...";
-set content [exec cat ./memory/risc8.text_3.uhex]
+set content [exec python ./tools/format_utils.py -w 8 -S 4 -n 3 -t uhex -s ./memory/build/risc8.text.o]
+#set content [exec cat ./memory/risc8.text_3.uhex]
 write_content_to_memory -instance_index 4 -content $content -content_in_hex -start_address 0 -word_count 1024
 
-puts "Flashing ram0...";
-set content [exec cat ./memory/risc8.data.uhex]
-write_content_to_memory -instance_index 0 -content $content -content_in_hex -start_address 0 -word_count 4096
 
-puts "Done!";
+write_source_data -instance_index 0 -value 0 -value_in_hex
+end_insystem_source_probe
 end_memory_edit
+puts "Done!";
 
 
 

+ 37 - 6
src/blocks/alu.sv

@@ -52,16 +52,40 @@ module alu(
 	assign sr = signedA >>> shmt;
 	
 
-	logic isAddSub, isMulDiv;
+	logic isAddSub;
 	logic cout0, cout1, gtu, overflow0;
 	logic [2:0] overflowCK;
 	logic [WORD*2-1:0] rmul, rdiv;
 	logic [WORD-1:0] radd, rsub;
+	
+	logic [WORD-1:0] w_sllc, w_sll, w_srl, w_srlc;
+	always_comb case(shmt)
+		3'd0:    {w_sllc,w_sll} = {8'd0,a};
+		3'd1:    {w_sllc,w_sll} = {7'd0,a,1'd0};
+		3'd2:    {w_sllc,w_sll} = {6'd0,a,2'd0};
+		3'd3:    {w_sllc,w_sll} = {5'd0,a,3'd0};
+		3'd4:    {w_sllc,w_sll} = {4'd0,a,4'd0};
+		3'd5:    {w_sllc,w_sll} = {3'd0,a,5'd0};
+		3'd6:    {w_sllc,w_sll} = {2'd0,a,6'd0};
+		3'd7:    {w_sllc,w_sll} = {1'd0,a,7'd0};
+		default: {w_sllc,w_sll} =      {a,8'd0};
+	endcase
+	
+	always_comb case(shmt)
+		3'd0:    {w_srl,w_srlc} =      {a,8'd0};
+		3'd1:    {w_srl,w_srlc} = {1'd0,a,7'd0};
+		3'd2:    {w_srl,w_srlc} = {2'd0,a,6'd0};
+		3'd3:    {w_srl,w_srlc} = {3'd0,a,5'd0};
+		3'd4:    {w_srl,w_srlc} = {4'd0,a,4'd0};
+		3'd5:    {w_srl,w_srlc} = {5'd0,a,3'd0};
+		3'd6:    {w_srl,w_srlc} = {6'd0,a,2'd0};
+		3'd7:    {w_srl,w_srlc} = {6'd0,a,1'd0};
+		default: {w_srl,w_srlc} = {8'd0,a};
+	endcase
 
 	always_comb begin
 		// Flags
 		isAddSub = (op == ALU_ADD)|(op == ALU_SUB);
-		isMulDiv = (op == ALU_MUL)|(op == ALU_DIV);
 
 		// Addition/Subtraction
 		{cout0,radd} = a + b + cin;
@@ -79,8 +103,15 @@ module alu(
 			rdiv = {a/b,a%b};
 		end
   		
-		r_high = (op == ALU_MUL) ? rmul[WORD*2-1:WORD] : rdiv[WORD-1:0];
-		r_high_en = isMulDiv;
+		case(op)
+			ALU_MUL: r_high = rmul[WORD*2-1:WORD];
+			ALU_DIV: r_high = rdiv[WORD*2-1:WORD];
+			ALU_SL:  r_high = w_sllc;
+			ALU_SR:  r_high = w_srlc;
+			default: r_high = 'd0;
+		endcase
+		//r_high = (op == ALU_MUL) ? rmul[WORD*2-1:WORD] : rdiv[WORD-1:0];
+		r_high_en = (op == ALU_MUL)|(op == ALU_DIV)|(op == ALU_SL)|(op == ALU_SR);
 
 		// Overflow/Underflow
 		overflowCK = {a[WORD-1], b[WORD-1], r[WORD-1]};	
@@ -103,8 +134,8 @@ module alu(
 		ALU_NAND: r = ~(a & b);
 		ALU_NOR : r = ~(a | b);
 		ALU_XNOR: r = ~(a ^ b);
-		ALU_SL:   r = a << shmt;
-		ALU_SR:   r = (sign) ? sr : a >> shmt;
+		ALU_SL:   r = w_sll;
+		ALU_SR:   r = w_srl;
 		ALU_RA:   r = {a[0], a[WORD-1:1]};
 		ALU_RAS:  r = {a[WORD-2:0], a[WORD-1]};
 		ALU_MUL:  r = rmul[WORD-1:0];

+ 9 - 9
src/blocks/rom.sv

@@ -78,7 +78,7 @@ module pseudo_rom(addr, clk, q);
 	parameter PROGRAM="";
 	parameter WIDTH=8;
 	parameter NUMWORDS=1024;
-	parameter BINARY=0;
+	parameter BINARY=1;
 	localparam AWIDTH=$clog2(NUMWORDS);
 	
 	input  reg 	clk;
@@ -136,16 +136,16 @@ module rom (
 	end
 	//always_ff@(posedge clock) q <= qn;
 
-	m9k_rom#({PROGRAM, "_0.mif"}, "rom0") rom0(addr0, clock, q0);
-	m9k_rom#({PROGRAM, "_1.mif"}, "rom1") rom1(addr1, clock, q1);
-	m9k_rom#({PROGRAM, "_2.mif"}, "rom2") rom2(addr2, clock, q2);
-	m9k_rom#({PROGRAM, "_3.mif"}, "rom3") rom3(addr3, clock, q3);
 	`ifdef SYNTHESIS
+	m9k_rom#({PROGRAM, ".0.mif"}, "rom0") rom0(addr0, clock, q0);
+	m9k_rom#({PROGRAM, ".1.mif"}, "rom1") rom1(addr1, clock, q1);
+	m9k_rom#({PROGRAM, ".2.mif"}, "rom2") rom2(addr2, clock, q2);
+	m9k_rom#({PROGRAM, ".3.mif"}, "rom3") rom3(addr3, clock, q3);
 	`else
-		//pseudo_rom#({PROGRAM, "_0"}) rom0(addr0, clock, q0);
-		//pseudo_rom#({PROGRAM, "_1"}) rom1(addr1, clock, q1);
-		//pseudo_rom#({PROGRAM, "_2"}) rom2(addr2, clock, q2);
-		//pseudo_rom#({PROGRAM, "_3"}) rom3(addr3, clock, q3);
+		pseudo_rom#({PROGRAM, ".0.mem"}) rom0(addr0, clock, q0);
+		pseudo_rom#({PROGRAM, ".1.mem"}) rom1(addr1, clock, q1);
+		pseudo_rom#({PROGRAM, ".2.mem"}) rom2(addr2, clock, q2);
+		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;

+ 15 - 2
src/const.sv

@@ -1,12 +1,25 @@
+// Global config
+
+// Master clock frequency
+`define MCLK_PLL_MUL 1
+`define MCLK_PLL_DIV 50
+// 50MHz * 3 / 25 = 6MHz
+
+// UART Clock divider:
+// UART0_DIV = MCLK_FREQ / (BAUD * 4) = 26
+`define BAUD 9600
+//`define UART0_DIV (50e6 * `MCLK_PLL_MUL / `MCLK_PLL_DIV) / (`BAUD * 4)
+`define UART0_CLK_DIV 26
+
 // Processor architecture
 `define OISC
- 
+`define SYNTHESIS 
 // Number of 16bit cells in ram 
 //`define RAM_SIZE 8192 
 `define RAM_SIZE 4096
 
 // Add debugging hardware to processor
-`define DEBUG
+//`define DEBUG
 
 `define ROMDIR "../../memory/build/"
 `define RAMDIR "../../memory/build/"

+ 5 - 0
src/empty.sv

@@ -0,0 +1,5 @@
+module empty(a, b);
+	input logic a;
+	output logic b;
+	always_comb b = ~a;
+endmodule

+ 5 - 2
src/project.sv

@@ -1,3 +1,5 @@
+`include "const.sv"
+
 interface processor_port(
 	input clk, rst,
 
@@ -46,9 +48,10 @@ module com_block(
 	reg uart0_recv;
 	reg uart0_transmit;
 	reg [7:0] tx_byte, rx_byte, rx_buf;
-	// Clock divide = 1e6 / (9600 * 4)
+	// Clock divide = 1e6 / (9600 * 4) = 26
+	// for 115200 clock divide = 2
 	//uart#(.CLOCK_DIVIDE(1302)) uart0(
-	uart#(.CLOCK_DIVIDE(26)) uart0(
+	uart#(.CLOCK_DIVIDE(`UART0_CLK_DIV)) uart0(
 			.clk(clk), 
 			.rst(0), 
 			.rx(uart0_rx),

+ 1 - 1
src/risc/cpu.sv

@@ -23,7 +23,7 @@ module risc8_cpu(processor_port port);
 	reg [31:0] instr; // Fetching 4x8bit instruction
 	reg [15:0] pc; // Instruction memory is 16bit in length
 	
-	rom#("../../memory/risc8.text") rom_block0(pc[11:0],  port.clk, instr);	
+	rom#("../../memory/build/risc8.text") rom_block0(pc[11:0],  port.clk, instr);	
 
 	risc8_cdi cdi0();
 	controller8 ctrl0(

+ 2 - 2
src/risc/datapath.sv

@@ -65,9 +65,9 @@ module datapath8(
 					alu_rhi <= '0;
 			end else begin
 
-			if((cdi.alu_op == ALU_ADD)||(cdi.alu_op == ALU_SUB))
+			if((cdi.alu_op == ALU_ADD)|(cdi.alu_op == ALU_SUB))
 					cinr <= cout;
-			if((cdi.alu_op == ALU_MUL)||(cdi.alu_op == ALU_DIV))
+			if((cdi.alu_op == ALU_MUL)|(cdi.alu_op == ALU_DIV)|(cdi.alu_op == ALU_SL)|(cdi.alu_op == ALU_SR))
 					alu_rhi <= alu_rhit;
 			end
 	end

+ 56 - 33
src/top.sv

@@ -8,7 +8,9 @@
 
 `ifdef OISC
 `include "oisc/cpu.sv"
-`elsif
+`endif
+
+`ifdef RISC
 `include "risc/cpu.sv"
 `endif
 
@@ -54,28 +56,24 @@ module top(
 	wire fclk; // Fast clock 		100MHz 		(for sdram)
 	wire aclk; // Auxiliary clock 	32,768kHz 	(for timers)
 
+	wire mclk0;
 	`ifdef DEBUG
-	wire mclk1, mclk0, clkd;
+	wire mclk_debug, clkd;
 	sys_ss#("CLKD", 1) sys_clkd(clkd);
-	sys_ss#("MCLK", 1) sys_mclk(mclk0);
-	assign mclk = clkd ? mclk0 : mclk1;
-
-	pll_clk pll_clk0 (
-			.inclk0(CLK50),
-			.areset(0),
-			.c0(fclk),
-			.c1(mclk1),
-			.c2(aclk)
-	);
+	sys_ss#("MCLK", 1) sys_mclk(mclk_debug);
+	assign mclk = clkd ? mclk_debug : mclk0;
 	`else
-	pll_clk pll_clk0 (
+	assign mclk = mclk0;
+	`endif
+
+	pll_clk#(.CLK1_MUL(`MCLK_PLL_MUL),.CLK1_DIV(`MCLK_PLL_DIV))
+	pll_clk0 (
 			.inclk0(CLK50),
 			.areset(0),
 			.c0(fclk),
-			.c1(mclk),
+			.c1(mclk0),
 			.c2(aclk)
 	);
-	`endif
 
 	//clk_dive#(28'd50) clk_div_mclk(CLK50, mclk);
 	//assign mclk = ~KEY[1];	
@@ -91,11 +89,11 @@ module top(
 	wire  		ram_rd_ack;
 	
 	`ifdef OISC
-	ram#({`RAMDIR, "oisc8.data"}) 
-	`elsif
-	ram#({`RAMDIR, "risc8.data"}) 
+	ram#({`RAMDIR, "oisc8.data"}) ram_block0(ram_addr[$clog2(`RAM_SIZE)-1:0], mclk, ram_wr_data, ram_wr_en, ram_rd_en, ram_rd_data);
+	`endif
+	`ifdef RISC
+	ram#({`RAMDIR, "risc8.data"}) ram_block0(ram_addr[$clog2(`RAM_SIZE)-1:0], mclk, ram_wr_data, ram_wr_en, ram_rd_en, ram_rd_data); 
 	`endif
-	ram_block0(ram_addr[$clog2(`RAM_SIZE)-1:0], mclk, ram_wr_data, ram_wr_en, ram_rd_en, ram_rd_data);
 	
 	`ifdef DEBUG
 		reg[23:0] ram_addr_rd_pr, ram_addr_wr_pr;
@@ -116,7 +114,7 @@ module top(
 	//sdram_block sdram0(
 	//	.mclk(mclk), 
 	//	.fclk(fclk), 
-	//	.rst_n(~rst), 
+	////	.rst_n(~rst), 
 	//	.ram_addr(racm_addr),
 	//	.ram_wr_data(ram_wr_data),
 	//	.ram_rd_data(ram_rd_data),
@@ -179,7 +177,8 @@ module top(
 	
 	`ifdef OISC
 	oisc8_cpu cpu_block0(port0);
-	`elsif
+	`endif
+	`ifdef RISC
 	risc8_cpu cpu_block0(port0);
 	`endif
 
@@ -238,10 +237,11 @@ module top_tb;
 				DRAM_CS_N,	
 				DRAM_BA	
 				);
-
-	initial if(top0.com0_addr == 8'h05) $display("%t UART0 send: %s", $time, top0.com0_wr); 
-
-
+	integer cycles = 0;
+	initial forever begin
+		#10ns CLK50 = ~CLK50;
+		cycles = cycles + 1;
+	end
 	initial begin
 			CLK50 = 0;
 			KEY[0] = 0;
@@ -251,14 +251,37 @@ module top_tb;
 
 			#1100ns;
 			KEY[0] = 1;
-			//#20us;
-			//KEY[1] = 0;
-			//#5us;
-			//KEY[1] = 1;
-			#10us;
-			$stop;
+			#400ns;
 	end
-	initial forever #10ns CLK50 = ~CLK50;
-	
 
+	
+	integer f;
+	initial begin
+	f = $fopen("oisc8_mod_u16_2.log","w");
+	forever begin
+	`ifdef OISC
+		if(top0.cpu_block0.pc0.pcr==16'h0009) break;
+		#1us;
+		$fwrite(f,"%H %b %H %H\n", 
+				top0.cpu_block0.pc0.pcr,
+				top0.cpu_block0.bus0.imm,
+				top0.cpu_block0.bus0.instr_dst,
+				top0.cpu_block0.bus0.instr_src
+		);
+	`endif
+	`ifdef RISC
+		if(top0.cpu_block0.rom_block0.ff_addr==16'h000b) break;
+		#1us;
+		//$fwrite(f,"%H %b %H %H\n", 
+		//		top0.cpu_block0.pc0.pcp,
+		//		top0.cpu_block0.bus0.imm,
+		//		top0.cpu_block0.bus0.instr_dst,
+		//		top0.cpu_block0.bus0.instr_src
+		//);
+	`endif
+	end
+	$fclose(f);
+	$finish;
+	end
+	
 endmodule

+ 1 - 1
tools/interface.py

@@ -483,7 +483,7 @@ def main(w):
                 spis = []
             w.refresh()
             w.addstr(4, 2, "Checking device in-system memory..")
-            # Attemt to close previous connections
+            # Attempt to close previous connections
             try:
                 q.end_memory_edit()
             except INSYS_MEM_ERROR:

+ 11 - 8
tools/tests.py

@@ -113,9 +113,11 @@ def rus_peasant(A, B):
     :return:
     """
     X = B
-    while X <= A / 2:
+    print('0: {:04X} {:04X}'.format(A, B))
+    while X <= A // 2:
         X <<= 1
-    print('A: {:04X} {:04X} {:04X}'.format(A, X, B))
+        print('X: {:04X}'.format(X))
+    print('A: {:04X} {:04X} {:04X}'.format(A//2, X, B))
     while A >= B:
         if A >= X:
             A -= X
@@ -152,19 +154,20 @@ def div16(a, b):
     for i in range(16):
         R = R << 1
         R[15] = N[i]
-        print('R='+R.hex, end='')
-        print(' D=' + D.hex, end='')
+        print(f'i={i:2d} R={R.hex} N={N.hex} D={D.hex}', end='')
         if R.uint >= D.uint:
             R = BitArray(bin=bin(R.uint - D.uint))
             R = BitArray(bin="0" * (16 - len(R)) + R.bin)
             Q[i] = True
+            print(f' R2={R.hex} Q={Q.hex}', end='')
         print()
     return Q.uint, R.uint
 
+
 def div8(a, b):
     from bitstring import BitArray
     ab = bin(a)[2:]
-    ab = '0'*(17-len(ab)) + ab
+    ab = '0' * (17 - len(ab)) + ab
     bb = bin(b)[2:]
     bb = '0' * (9 - len(bb)) + bb
     rd1 = BitArray(bin=ab)
@@ -202,10 +205,10 @@ def div8(a, b):
 
 
 if __name__ == '__main__':
-    # d, r = div16(5, 16)
-    # print("%d and %d" % (d, r))
+    d, r = div16(50000, 2)
+    print("%x [%d] and %x [%d]" % (d, d, r, r))
     # pass
-    calc_sieve(2**16)
+    # calc_sieve(2**16)
 
     # calc(255)
     # res = rus_peasant(666, 48)[0]