Bläddra i källkod

Restruction & OISC

Restructured project so that each procesor specific verilog files are
included from "cpu.sv" file. Included basic structure and skeleton
architecture for OISC.
Min 6 år sedan
förälder
incheckning
a075e40b99
6 ändrade filer med 170 tillägg och 18 borttagningar
  1. 19 13
      src/blocks/rom.sv
  2. 77 0
      src/oisc/cpu.sv
  3. 51 0
      src/oisc/oisc.sv
  4. 4 0
      src/risc/cpu.sv
  5. 0 0
      src/risc/risc.sv
  6. 19 5
      src/top.sv

+ 19 - 13
src/blocks/rom.sv

@@ -11,10 +11,13 @@ module m9k_rom (
 
 	parameter PROGRAM="";
 	parameter NAME="";
+	parameter WIDTH=8;
+	parameter NUMWORDS=1024;
+	localparam AWIDTH=$clog2(NUMWORDS);
 
-	input	[9:0]  address;
+	input	[AWIDTH-1:0]  address;
 	input	  clock;
-	output	[7:0]  q;
+	output	[WIDTH-1:0]  q;
 `ifndef ALTERA_RESERVED_QIS
 // synopsys translate_off
 `endif
@@ -23,8 +26,8 @@ module m9k_rom (
 // synopsys translate_on
 `endif
 
-	wire [7:0] sub_wire0;
-	wire [7:0] q = sub_wire0[7:0];
+	wire [WIDTH-1:0] sub_wire0;
+	wire [WIDTH-1:0] q = sub_wire0[WIDTH-1:0];
 	
 	initial $display("Initialising ROM Memory: %s", PROGRAM);
 
@@ -44,7 +47,7 @@ module m9k_rom (
 				.clocken1 (1'b1),
 				.clocken2 (1'b1),
 				.clocken3 (1'b1),
-				.data_a ({8{1'b1}}),
+				.data_a ({WIDTH{1'b1}}),
 				.data_b (1'b1),
 				.eccstatus (),
 				.q_b (),
@@ -60,31 +63,34 @@ module m9k_rom (
 		altsyncram_component.intended_device_family = "Cyclone IV E",
 		altsyncram_component.lpm_hint = {"ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME=", NAME},
 		altsyncram_component.lpm_type = "altsyncram",
-		altsyncram_component.numwords_a = 1024,
+		altsyncram_component.numwords_a = NUMWORDS,
 		altsyncram_component.operation_mode = "ROM",
 		altsyncram_component.outdata_aclr_a = "NONE",
 		altsyncram_component.outdata_reg_a = "UNREGISTERED",
 		altsyncram_component.ram_block_type = "M9K",
-		altsyncram_component.widthad_a = 10,
-		altsyncram_component.width_a = 8,
+		altsyncram_component.widthad_a = AWIDTH,
+		altsyncram_component.width_a = WIDTH,
 		altsyncram_component.width_byteena_a = 1;
 
 endmodule 
 
 module pseudo_rom(addr, clk, q);
 	parameter PROGRAM="";
+	parameter WIDTH=8;
+	parameter NUMWORDS=1024;
+	localparam AWIDTH=$clog2(NUMWORDS);
 	
 	input  reg 	clk;
-	input  wire [9:0] addr;
-	output  reg [7:0] q;
+	input  wire [AWIDTH-1:0] addr;
+	output  reg [WIDTH-1:0] q;
 	
 	initial $display("Initialising ROM Memory: %s", PROGRAM);
 	
-	reg [9:0] addr0;
-	logic [7:0] rom [2**10:0];
+	reg [AWIDTH-1:0] addr0;
+	logic [WIDTH-1:0] rom [NUMWORDS:0];
 	initial $readmemh(PROGRAM, rom);
 	always_ff@(posedge clk) addr0 <= addr; 	
-	assign q[7:0] = rom[addr0];
+	assign q = rom[addr0];
 
 endmodule
 

+ 77 - 0
src/oisc/cpu.sv

@@ -0,0 +1,77 @@
+`include "oisc.sv"
+import oisc8_pkg::*;
+
+module oisc8_cpu(processor_port port);
+	
+	wire [7:0] data_bus;
+	wire [8*2-1:0] inst_bus;  // FIXME: replace 8 with ASIZE
+	
+	IBus bus0(
+			.clk(port.clk),
+			.rst(port.rst),
+			.instr(instr_bus),
+			.data(data_bus)
+	);
+
+	pc_block#(.PROGRAM("../../memory/oisc8.text")) pc0(bus0);
+	alu_block alu0(bus0);
+
+endmodule
+
+module pc_block(IBus bus);
+	parameter PROGRAM = "";
+	reg[15:0] pc, pcn; // Program counter
+
+	`ifdef SYNTHESIS
+	m9k_rom#(
+			.PROGRAM({PROGRAM, ".mif"}), 
+			.NAME("rom0"),
+			.WIDTH(16),
+			.NUMWORDS(2048)
+	)
+	`else
+	pseudo_rom#(
+			.PROGRAM({PROGRAM, ".mem"}), 
+			.WIDTH(16),
+			.NUMWORDS(2048)
+	) 
+	`endif
+		rom0(pcn[11:0], bus.clk, bus.instr);
+
+	assign pcn = pc + 1;  // Next pc 
+	always_ff@(posedge bus.clk) begin
+		if(bus.rst) pc <= 0;
+		else pc <= pcn;
+	end
+
+endmodule
+
+module alu_block(IBus bus);
+	reg[7:0] acc;
+	logic add_carry, sub_carry;
+	Port #(.ADDR(ACCI), .IMMIDATE(1)) p_acc0(
+			.bus(bus),
+			.data_from_bus(acc),
+			.data_to_bus(acc)
+	);
+	
+	reg[7:0] add_input;
+	reg[7:0] add_output;
+	assign {add_carry,add_output} = add_input + acc;
+	Port #(.ADDR(ADDI), .IMMIDATE(1)) p_add0(
+			.bus(bus),
+			.data_from_bus(add_input),
+			.data_to_bus(add_output)
+	);
+	
+	reg[7:0] sub_input;
+	reg[7:0] sub_output;
+	assign {sub_carry,sub_output} = sub_input - acc;
+	Port #(.ADDR(SUB)) p_sub0(
+			.bus(bus),
+			.data_from_bus(sub_input),
+			.data_to_bus(sub_output)
+	);	
+
+endmodule
+	

+ 51 - 0
src/oisc/oisc.sv

@@ -0,0 +1,51 @@
+package oisc8_pkg;
+
+	// Instruction address bus width
+	parameter ASIZE = 8;
+
+	typedef enum logic [ASIZE-1:0] {
+		NONE=8'd0,
+		ACC =8'd1,
+		ACCI=8'd2,
+		ADD =8'd3,
+		ADDI=8'd4,
+		SUB =8'd5,
+		SUBI=8'd6
+	} e_iaddr;
+
+endpackage
+
+interface IBus(
+	input logic clk, rst,
+	inout wire[7:0] data,
+	input wire[8*2-1:0] instr  // FIXME, replace 8 with ASIZE
+	);
+endinterface
+
+module Port(
+		IBus bus,
+		output reg[7:0] data_from_bus,
+		input  reg[7:0] data_to_bus
+	);
+	
+
+	localparam ASIZE = 8;  // FIXME: take from oisc8_pkg
+	parameter ADDR = 8'd0;
+	parameter IMMIDATE = 0;
+
+	reg rd, wr;
+	assign rd = bus.instr[ASIZE-1:0] == ADDR;
+	assign wr = bus.instr[ASIZE*2-1:ASIZE] == ADDR;
+	assign bus.data = wr ? data_to_bus : 'bZ;
+	always_ff@(posedge bus.clk) begin
+		if(bus.rst) begin
+			data_from_bus <= 0;
+		end else begin
+			if(IMMIDATE == 0)
+				data_from_bus <= rd ? bus.data : data_from_bus;
+			else 
+				data_from_bus <= rd ? bus.data : bus.instr[ASIZE*2-1:ASIZE];
+		end
+	end
+
+endmodule

+ 4 - 0
src/risc/cpu.sv

@@ -1,3 +1,7 @@
+`include "risc.sv"
+`include "controller.sv"
+`include "datapath.sv"
+
 import risc8_pkg::*;
 import alu_pkg::*;
 

src/risc/general.sv → src/risc/risc.sv


+ 19 - 5
src/top.sv

@@ -3,6 +3,16 @@
  * It includes all cpu external modules like UART
  * and SDRAM controller. 
 */
+
+// Compile OISC?
+`define OISC
+
+`ifdef OISC
+`include "oisc/cpu.sv"
+`elsif
+`include "risc/cpu.sv"
+`endif
+
 module top(
 	input  			CLK50,		// Clock 50MHz
 
@@ -123,8 +133,12 @@ module top(
 		.com_rd(com0_rd),
 		.com_interrupt(com0_interrupt)
 	);
-
+	
+	`ifdef OISC
+	oisc8_cpu cpu_block0(port0);
+	`elsif
 	risc8_cpu cpu_block0(port0);
+	`endif
 
 endmodule
 
@@ -194,10 +208,10 @@ module top_tb;
 
 			#1100ns;
 			KEY[0] = 1;
-			#20us;
-			KEY[1] = 0;
-			#5us;
-			KEY[1] = 1;
+			//#20us;
+			//KEY[1] = 0;
+			//#5us;
+			//KEY[1] = 1;
 			#300us;
 			$stop;
 	end