浏览代码

Project restructure

Made a generic layout that is located in src/top.sv. Added interface
"processor_port" so different processor designs could be easily swapped
without affecting memory or comunication modules.
Min 6 年之前
父节点
当前提交
9d5c8e7121

+ 68 - 24
UCL_project_y3.qsf

@@ -38,7 +38,7 @@
 
 set_global_assignment -name FAMILY "Cyclone IV E"
 set_global_assignment -name DEVICE EP4CE22F17C6
-set_global_assignment -name TOP_LEVEL_ENTITY io_unit
+set_global_assignment -name TOP_LEVEL_ENTITY top
 set_global_assignment -name ORIGINAL_QUARTUS_VERSION 18.1.0
 set_global_assignment -name PROJECT_CREATION_TIME_DATE "13:15:52  SEPTEMBER 19, 2019"
 set_global_assignment -name LAST_QUARTUS_VERSION "18.1.0 Lite Edition"
@@ -53,40 +53,82 @@ set_global_assignment -name EDA_TIME_SCALE "1 ps" -section_id eda_simulation
 set_global_assignment -name EDA_OUTPUT_DATA_FORMAT "SYSTEMVERILOG HDL" -section_id eda_simulation
 set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
 set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
-set_location_assignment PIN_J15 -to keys[0]
-set_location_assignment PIN_E1 -to keys[1]
-set_location_assignment PIN_A15 -to leds[0]
-set_location_assignment PIN_A13 -to leds[1]
-set_location_assignment PIN_B13 -to leds[2]
-set_location_assignment PIN_A11 -to leds[3]
-set_location_assignment PIN_D1 -to leds[4]
-set_location_assignment PIN_F3 -to leds[5]
-set_location_assignment PIN_B1 -to leds[6]
-set_location_assignment PIN_L3 -to leds[7]
-set_location_assignment PIN_M1 -to switches[0]
-set_location_assignment PIN_T8 -to switches[1]
-set_location_assignment PIN_B9 -to switches[2]
-set_location_assignment PIN_M15 -to switches[3]
 set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF
 set_global_assignment -name EDA_TEST_BENCH_ENABLE_STATUS TEST_BENCH_MODE -section_id eda_simulation
 set_global_assignment -name EDA_NATIVELINK_SIMULATION_TEST_BENCH testbench_1 -section_id eda_simulation
 set_global_assignment -name EDA_TEST_BENCH_NAME testbench_1 -section_id eda_simulation
 set_global_assignment -name EDA_DESIGN_INSTANCE_NAME NA -section_id testbench_1
 set_global_assignment -name EDA_TEST_BENCH_MODULE_NAME testbench_1 -section_id testbench_1
-set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
-set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
-set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
 set_global_assignment -name EDA_TEST_BENCH_FILE src/blocks/reg_file_tb.sv -section_id testbench_1
 set_global_assignment -name EDA_TEST_BENCH_FILE src/blocks/memory.sv -section_id testbench_1
 set_global_assignment -name EDA_TEST_BENCH_FILE src/blocks/alu.sv -section_id testbench_1
 set_global_assignment -name EDA_TEST_BENCH_FILE src/datapath.sv -section_id testbench_1
 set_global_assignment -name EDA_TEST_BENCH_FILE src/cpu.sv -section_id testbench_1
 set_global_assignment -name EDA_TEST_BENCH_FILE src/controller.sv -section_id testbench_1
-set_location_assignment PIN_R8 -to clk
-set_location_assignment PIN_D3 -to rx
-set_location_assignment PIN_C3 -to tx
-set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
-set_global_assignment -name SYSTEMVERILOG_FILE src/risc/io_unit.sv
+set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005
+set_location_assignment PIN_P2 -to DRAM_ADDR[0]
+set_location_assignment PIN_L4 -to DRAM_ADDR[12]
+set_location_assignment PIN_N1 -to DRAM_ADDR[11]
+set_location_assignment PIN_N2 -to DRAM_ADDR[10]
+set_location_assignment PIN_N5 -to DRAM_ADDR[1]
+set_location_assignment PIN_N6 -to DRAM_ADDR[2]
+set_location_assignment PIN_M8 -to DRAM_ADDR[3]
+set_location_assignment PIN_P8 -to DRAM_ADDR[4]
+set_location_assignment PIN_T7 -to DRAM_ADDR[5]
+set_location_assignment PIN_N8 -to DRAM_ADDR[6]
+set_location_assignment PIN_T6 -to DRAM_ADDR[7]
+set_location_assignment PIN_R1 -to DRAM_ADDR[8]
+set_location_assignment PIN_P1 -to DRAM_ADDR[9]
+set_location_assignment PIN_G2 -to DRAM_DQ[0]
+set_location_assignment PIN_G1 -to DRAM_DQ[1]
+set_location_assignment PIN_L8 -to DRAM_DQ[2]
+set_location_assignment PIN_K5 -to DRAM_DQ[3]
+set_location_assignment PIN_K2 -to DRAM_DQ[4]
+set_location_assignment PIN_J2 -to DRAM_DQ[5]
+set_location_assignment PIN_J1 -to DRAM_DQ[6]
+set_location_assignment PIN_R7 -to DRAM_DQ[7]
+set_location_assignment PIN_T4 -to DRAM_DQ[8]
+set_location_assignment PIN_T2 -to DRAM_DQ[9]
+set_location_assignment PIN_T3 -to DRAM_DQ[10]
+set_location_assignment PIN_R3 -to DRAM_DQ[11]
+set_location_assignment PIN_R5 -to DRAM_DQ[12]
+set_location_assignment PIN_P3 -to DRAM_DQ[13]
+set_location_assignment PIN_N3 -to DRAM_DQ[14]
+set_location_assignment PIN_K1 -to DRAM_DQ[15]
+set_location_assignment PIN_P6 -to DRAM_CS_N
+set_location_assignment PIN_R4 -to DRAM_CLK
+set_location_assignment PIN_L7 -to DRAM_CKE
+set_location_assignment PIN_M6 -to DRAM_BA[0]
+set_location_assignment PIN_M7 -to DRAM_BA[1]
+set_location_assignment PIN_L1 -to DRAM_CAS_N
+set_location_assignment PIN_C2 -to DRAM_WE_N
+set_location_assignment PIN_L2 -to DRAM_RAS_N
+set_location_assignment PIN_R6 -to DRAM_DQM[0]
+set_location_assignment PIN_T5 -to DRAM_DQM[1]
+set_location_assignment PIN_L3 -to LED[7]
+set_location_assignment PIN_D3 -to RX
+set_location_assignment PIN_C3 -to TX
+set_location_assignment PIN_A15 -to LED[0]
+set_location_assignment PIN_A13 -to LED[1]
+set_location_assignment PIN_B13 -to LED[2]
+set_location_assignment PIN_A11 -to LED[3]
+set_location_assignment PIN_D1 -to LED[4]
+set_location_assignment PIN_F3 -to LED[5]
+set_location_assignment PIN_B1 -to LED[6]
+set_location_assignment PIN_E1 -to KEY[1]
+set_location_assignment PIN_J15 -to KEY[0]
+set_location_assignment PIN_M1 -to SWITCH[0]
+set_location_assignment PIN_T8 -to SWITCH[1]
+set_location_assignment PIN_B9 -to SWITCH[2]
+set_location_assignment PIN_M15 -to SWITCH[3]
+set_location_assignment PIN_R8 -to CLK50
+set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
+set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
+set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
+set_global_assignment -name SYSTEMVERILOG_FILE src/project.sv
+set_global_assignment -name SYSTEMVERILOG_FILE src/top.sv
+set_global_assignment -name VERILOG_FILE src/blocks/fifo.v
+set_global_assignment -name SYSTEMVERILOG_FILE src/blocks/sdram_control.sv
 set_global_assignment -name SYSTEMVERILOG_FILE src/risc/general.sv
 set_global_assignment -name SYSTEMVERILOG_FILE src/risc/datapath.sv
 set_global_assignment -name SYSTEMVERILOG_FILE src/risc/cpu.sv
@@ -97,4 +139,6 @@ set_global_assignment -name VERILOG_FILE src/blocks/uart.v
 set_global_assignment -name SYSTEMVERILOG_FILE src/blocks/instr_mem.sv
 set_global_assignment -name SYSTEMVERILOG_FILE src/blocks/reg_file.sv
 set_global_assignment -name SYSTEMVERILOG_FILE src/blocks/memory.sv
-set_global_assignment -name SYSTEMVERILOG_FILE src/blocks/alu.sv
+set_global_assignment -name SYSTEMVERILOG_FILE src/blocks/alu.sv
+set_global_assignment -name QIP_FILE quartus/pll_clk.qip
+set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

+ 12 - 0
quartus/pll_clk.ppf

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE pinplan>
+<pinplan intended_family="Cyclone IV E" variation_name="pll_clk" megafunction_name="ALTPLL" specifies="all_ports">
+<global>
+<pin name="areset" direction="input" scope="external"  />
+<pin name="inclk0" direction="input" scope="external" source="clock"  />
+<pin name="c0" direction="output" scope="external" source="clock"  />
+<pin name="c1" direction="output" scope="external" source="clock"  />
+<pin name="c2" direction="output" scope="external" source="clock"  />
+
+</global>
+</pinplan>

+ 5 - 0
quartus/pll_clk.qip

@@ -0,0 +1,5 @@
+set_global_assignment -name IP_TOOL_NAME "ALTPLL"
+set_global_assignment -name IP_TOOL_VERSION "18.1"
+set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll_clk.v"]
+set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_clk.ppf"]

+ 368 - 0
quartus/pll_clk.v

@@ -0,0 +1,368 @@
+// megafunction wizard: %ALTPLL%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: altpll 
+
+// ============================================================
+// File Name: pll_clk.v
+// Megafunction Name(s):
+// 			altpll
+//
+// Simulation Library Files(s):
+// 			altera_mf
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 18.1.0 Build 625 09/12/2018 SJ Lite Edition
+// ************************************************************
+
+
+//Copyright (C) 2018  Intel Corporation. All rights reserved.
+//Your use of Intel Corporation's design tools, logic functions 
+//and other software and tools, and its AMPP partner logic 
+//functions, and any output files from any of the foregoing 
+//(including device programming or simulation files), and any 
+//associated documentation or information are expressly subject 
+//to the terms and conditions of the Intel Program License 
+//Subscription Agreement, the Intel Quartus Prime License Agreement,
+//the Intel FPGA IP License Agreement, or other applicable license
+//agreement, including, without limitation, that your use is for
+//the sole purpose of programming logic devices manufactured by
+//Intel and sold by Intel or its authorized distributors.  Please
+//refer to the applicable agreement for further details.
+
+
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+module pll_clk (
+	areset,
+	inclk0,
+	c0,
+	c1,
+	c2);
+
+	input	  areset;
+	input	  inclk0;
+	output	  c0;
+	output	  c1;
+	output	  c2;
+`ifndef ALTERA_RESERVED_QIS
+// synopsys translate_off
+`endif
+	tri0	  areset;
+`ifndef ALTERA_RESERVED_QIS
+// synopsys translate_on
+`endif
+
+	wire [4:0] sub_wire0;
+	wire [0:0] sub_wire6 = 1'h0;
+	wire [2:2] sub_wire3 = sub_wire0[2:2];
+	wire [1:1] sub_wire2 = sub_wire0[1:1];
+	wire [0:0] sub_wire1 = sub_wire0[0:0];
+	wire  c0 = sub_wire1;
+	wire  c1 = sub_wire2;
+	wire  c2 = sub_wire3;
+	wire  sub_wire4 = inclk0;
+	wire [1:0] sub_wire5 = {sub_wire6, sub_wire4};
+
+	altpll	altpll_component (
+				.areset (areset),
+				.inclk (sub_wire5),
+				.clk (sub_wire0),
+				.activeclock (),
+				.clkbad (),
+				.clkena ({6{1'b1}}),
+				.clkloss (),
+				.clkswitch (1'b0),
+				.configupdate (1'b0),
+				.enable0 (),
+				.enable1 (),
+				.extclk (),
+				.extclkena ({4{1'b1}}),
+				.fbin (1'b1),
+				.fbmimicbidir (),
+				.fbout (),
+				.fref (),
+				.icdrclk (),
+				.locked (),
+				.pfdena (1'b1),
+				.phasecounterselect ({4{1'b1}}),
+				.phasedone (),
+				.phasestep (1'b1),
+				.phaseupdown (1'b1),
+				.pllena (1'b1),
+				.scanaclr (1'b0),
+				.scanclk (1'b0),
+				.scanclkena (1'b1),
+				.scandata (1'b0),
+				.scandataout (),
+				.scandone (),
+				.scanread (1'b0),
+				.scanwrite (1'b0),
+				.sclkout0 (),
+				.sclkout1 (),
+				.vcooverrange (),
+				.vcounderrange ());
+	defparam
+		altpll_component.bandwidth_type = "AUTO",
+		altpll_component.clk0_divide_by = 1,
+		altpll_component.clk0_duty_cycle = 50,
+		altpll_component.clk0_multiply_by = 2,
+		altpll_component.clk0_phase_shift = "0",
+		altpll_component.clk1_divide_by = 50,
+		altpll_component.clk1_duty_cycle = 50,
+		altpll_component.clk1_multiply_by = 1,
+		altpll_component.clk1_phase_shift = "0",
+		altpll_component.clk2_divide_by = 390625,
+		altpll_component.clk2_duty_cycle = 50,
+		altpll_component.clk2_multiply_by = 256,
+		altpll_component.clk2_phase_shift = "0",
+		altpll_component.compensate_clock = "CLK0",
+		altpll_component.inclk0_input_frequency = 20000,
+		altpll_component.intended_device_family = "Cyclone IV E",
+		altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll_clk",
+		altpll_component.lpm_type = "altpll",
+		altpll_component.operation_mode = "NORMAL",
+		altpll_component.pll_type = "AUTO",
+		altpll_component.port_activeclock = "PORT_UNUSED",
+		altpll_component.port_areset = "PORT_USED",
+		altpll_component.port_clkbad0 = "PORT_UNUSED",
+		altpll_component.port_clkbad1 = "PORT_UNUSED",
+		altpll_component.port_clkloss = "PORT_UNUSED",
+		altpll_component.port_clkswitch = "PORT_UNUSED",
+		altpll_component.port_configupdate = "PORT_UNUSED",
+		altpll_component.port_fbin = "PORT_UNUSED",
+		altpll_component.port_inclk0 = "PORT_USED",
+		altpll_component.port_inclk1 = "PORT_UNUSED",
+		altpll_component.port_locked = "PORT_UNUSED",
+		altpll_component.port_pfdena = "PORT_UNUSED",
+		altpll_component.port_phasecounterselect = "PORT_UNUSED",
+		altpll_component.port_phasedone = "PORT_UNUSED",
+		altpll_component.port_phasestep = "PORT_UNUSED",
+		altpll_component.port_phaseupdown = "PORT_UNUSED",
+		altpll_component.port_pllena = "PORT_UNUSED",
+		altpll_component.port_scanaclr = "PORT_UNUSED",
+		altpll_component.port_scanclk = "PORT_UNUSED",
+		altpll_component.port_scanclkena = "PORT_UNUSED",
+		altpll_component.port_scandata = "PORT_UNUSED",
+		altpll_component.port_scandataout = "PORT_UNUSED",
+		altpll_component.port_scandone = "PORT_UNUSED",
+		altpll_component.port_scanread = "PORT_UNUSED",
+		altpll_component.port_scanwrite = "PORT_UNUSED",
+		altpll_component.port_clk0 = "PORT_USED",
+		altpll_component.port_clk1 = "PORT_USED",
+		altpll_component.port_clk2 = "PORT_USED",
+		altpll_component.port_clk3 = "PORT_UNUSED",
+		altpll_component.port_clk4 = "PORT_UNUSED",
+		altpll_component.port_clk5 = "PORT_UNUSED",
+		altpll_component.port_clkena0 = "PORT_UNUSED",
+		altpll_component.port_clkena1 = "PORT_UNUSED",
+		altpll_component.port_clkena2 = "PORT_UNUSED",
+		altpll_component.port_clkena3 = "PORT_UNUSED",
+		altpll_component.port_clkena4 = "PORT_UNUSED",
+		altpll_component.port_clkena5 = "PORT_UNUSED",
+		altpll_component.port_extclk0 = "PORT_UNUSED",
+		altpll_component.port_extclk1 = "PORT_UNUSED",
+		altpll_component.port_extclk2 = "PORT_UNUSED",
+		altpll_component.port_extclk3 = "PORT_UNUSED",
+		altpll_component.width_clock = 5;
+
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
+// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
+// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
+// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
+// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
+// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
+// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
+// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
+// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
+// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
+// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
+// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
+// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "Any"
+// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "50"
+// Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "1"
+// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
+// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
+// Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000"
+// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "100.000000"
+// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "1.000000"
+// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "0.032768"
+// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
+// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
+// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
+// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
+// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
+// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000"
+// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
+// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0"
+// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
+// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg"
+// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "deg"
+// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
+// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
+// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
+// Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0"
+// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "1"
+// Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "1"
+// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.00000000"
+// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "1.00000000"
+// Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "0.03276800"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz"
+// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
+// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
+// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
+// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
+// Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "0.00000000"
+// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
+// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg"
+// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "deg"
+// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
+// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
+// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
+// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll_clk.mif"
+// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
+// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
+// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
+// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
+// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
+// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
+// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
+// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
+// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
+// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
+// Retrieval info: PRIVATE: STICKY_CLK2 STRING "1"
+// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
+// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
+// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
+// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
+// Retrieval info: PRIVATE: USE_CLK1 STRING "1"
+// Retrieval info: PRIVATE: USE_CLK2 STRING "1"
+// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
+// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
+// Retrieval info: PRIVATE: USE_CLKENA2 STRING "0"
+// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
+// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
+// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1"
+// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
+// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "2"
+// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
+// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "50"
+// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
+// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "1"
+// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
+// Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "390625"
+// Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50"
+// Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "256"
+// Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0"
+// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
+// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
+// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
+// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
+// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED"
+// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
+// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
+// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
+// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED"
+// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
+// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
+// Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"
+// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
+// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
+// Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2"
+// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
+// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
+// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
+// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
+// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
+// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
+// Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_clk.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_clk.ppf TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_clk.inc FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_clk.cmp FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_clk.bsf FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_clk_inst.v FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_clk_bb.v FALSE
+// Retrieval info: LIB_FILE: altera_mf
+// Retrieval info: CBX_MODULE_PREFIX: ON

+ 10 - 0
simulation/modelsim/risc_tb_wave.do

@@ -0,0 +1,10 @@
+clk = 0
+rst = 0
+mem_wr = 0
+pc = 00101010
+instr = 10110000
+imm = 00101010
+mem_addr = 00001101
+mem_data = 00001101
+mem_rd_data = xxxxxxxx
+outvalue = 00000000

+ 120 - 75
src/blocks/alu.sv

@@ -24,139 +24,184 @@ endpackage
 import alu_pkg::*;
 
 module alu(
-	srcA, srcB, result, op, cin, sign, zero, cout, gt, equal, overflow
+	a, b, r, op, cin, sign, zero, cout, gt, eq, overflow
 );
 	parameter WORD=8;
 	localparam WSIZE=$clog2(WORD);
 
 	input e_alu_op 			op;
 	input logic 			cin, sign;
-	input logic [WORD-1:0] 	srcA, srcB;
+	input logic [WORD-1:0] 	a, b;
 	
-	output logic 			zero, cout, gt, equal, overflow;
-	output logic [WORD-1:0] result;
+	output logic 			zero, cout, gt, eq, overflow;
+	output logic [WORD-1:0] r;
 	
 	logic [WSIZE-1:0] shmt;
-	assign shmt = srcB[WSIZE-1:0];
+	assign shmt = b[WSIZE-1:0];
 	
 	// FIXME: Seems like there's a bug with ModelSim or Verilog
 	// Object must be signed to do arithmetic shift right
 	// casting $signed does not work. Tho folloing passes:
  	// assert(8'sb1000_0100 >>> 2 == 8'sb1110_0001);
 	reg signed [WORD-1:0] signedA, sr;
-	assign signedA = srcA;
+	assign signedA = a;
 	assign sr = signedA >>> shmt;
+	
+	logic arithmeticOp, coutF;
+	assign arithmeticOp = (op == ALU_ADD || op == ALU_SUB || op == ALU_MUL || op == ALU_DIV);
+
+	// Overflow/Underflow flag	
+	logic [1:0] overLSB;
+	logic overFlag;
+	assign overLSB = {a[WORD-1], b[WORD-1], r[WORD-1]};	
+	assign overFlag = overLSB == 3'b110 || overLSB == 3'b001 ? 1 : 0;
+	assign overflow = sign && arithmeticOp ? overFlag : 0;	
+	
+	// Carry out flag
+	assign cout = arithmeticOp && ~sign ? coutF : 0;	
 
 	always_comb begin
 	case(op)
-		ALU_ADD: {cout, result} = (srcA + cin) + srcB;
-		ALU_SUB: {cout, result} = (srcA + cin) - srcB;
-		ALU_AND: result = srcA & srcB;
-		ALU_OR : result = srcA | srcB;
-		ALU_XOR: result = srcA ^ srcB;
-		ALU_NAND: result = ~(srcA & srcB);
-		ALU_NOR : result = ~(srcA | srcB);
-		ALU_XNOR: result = ~(srcA ^ srcB);
-		ALU_SL: result = srcA << shmt;
-		ALU_SR: result = (sign) ? sr : srcA >> shmt;
-		ALU_ROL: result = {srcA[0], srcA[WORD-1:1]};
-		ALU_ROR: result = {srcA[WORD-2:0], srcA[WORD-1]};
-		ALU_MUL: result = srcA * srcB;
-		ALU_DIV: result = srcA / srcB;
-		ALU_MOD: result = srcA % srcB;
-		default: result = 0;
+		ALU_ADD: {coutF, r} = a + b + cin;
+		ALU_SUB: {coutF, r} = a - b - cin;
+		ALU_AND: r = a & b;
+		ALU_OR : r = a | b;
+		ALU_XOR: r = a ^ b;
+		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_ROL: r = {a[0], a[WORD-1:1]};
+		ALU_ROR: r = {a[WORD-2:0], a[WORD-1]};
+		ALU_MUL: r = a * b;
+		ALU_DIV: r = a / b;
+		ALU_MOD: r = a % b;
+		default: r = 0;
 	endcase
 	end
 
-	assign zero = result == 0;
-	assign equal = srcA == srcB;
-	assign gt = srcA > srcB;
+	assign zero = r == 0;
+	assign eq = a == b;
+	assign gt = a > b;
 
 endmodule
 
+`timescale 1ns / 1ns
 module alu_tb;
 	e_alu_op op;
-	logic [7:0]srcA, srcB, result;
-	logic overflow, zero, cin, cout, gt, equal, sign;
+	reg [7:0]a, b, r;
+	logic overflow, zero, cin, cout, gt, eq, sign;
+	
 	
 	alu test_alu(
 		.op(op),
-		.srcA(srcA), 
-		.srcB(srcB),
-		.result(result),
+		.a(a), 
+		.b(b),
+		.r(r),
 		.zero(zero),
 		.cin(cin),
 		.cout(cout),
 		.gt(gt),
-		.equal(equal),
+		.eq(eq),
 		.sign(sign),
 		.overflow(overflow)
 	);
 
-	task test;
+	// Test & print result
+	task testprint;
 		input e_alu_op t_op;
 		input [7:0] t_a, t_b, t_e;
+		input e_c, e_o, binary;
 		begin
+			reg signed [7:0]t_sa, t_sb, t_sr, t_se;
+			string s_a, s_b, s_r, s_e;
 			op = t_op;
-			srcA = t_a;
-			srcB = t_b;
+			a = t_a;
+			b = t_b;	
 			#1
-			$write("ALU Test: %d %8s %d = %d ", 
-				(sign) ? $signed(t_a) : t_a,
-				op.name, 
-				(sign) ? $signed(t_b) : t_b,
-				(sign) ? $signed(result) : result
-			);
-			if (result == t_e) $display("(correct)");
-			else $display("(expected %d)", t_e); 
-			assert(result == t_e);	
+			t_sa = $signed(t_a);		
+			t_sb = $signed(t_b);		
+			t_sr = $signed(r);		
+			t_se = $signed(t_e);
+			if(binary) begin
+			$sformat(s_a,"%b", t_sa);
+			$sformat(s_b,"%b", t_sb);
+			$sformat(s_r,"%b", t_sr);
+			$sformat(s_e,"%b", t_se);
+			end 
+			else if (sign) begin
+			$sformat(s_a,"%d", t_sa);
+			$sformat(s_b,"%d", t_sb);
+			$sformat(s_r,"%d", t_sr);
+			$sformat(s_e,"%d", t_se);
+			end 
+			else begin
+			$sformat(s_a,"%d", t_a);
+			$sformat(s_b,"%d", t_b);
+			$sformat(s_r,"%d", r);
+			$sformat(s_e,"%d", t_e);
+			end
+			
+			$display("ALU Test %4t00ps: %s %8s %s=%s C=%b O=%b", 
+				$time, s_a, "unknown op", s_b, s_r, cout, overflow);
+			if (r != t_e || cout != e_c || overflow != e_o) begin 
+				$error("Incorrect: expected R=%s C=%b O=%b", s_e, e_c, e_o);
+			end
 		end		
 	endtask
 	
+	task test;
+		input e_alu_op t_op;
+		input [7:0] t_a, t_b, t_e;
+		input e_c, e_o;
+		testprint(t_op, t_a, t_b, t_e, e_c, e_o, 0);
+	endtask
+
 	task testb;
 		input e_alu_op t_op;
 		input [7:0] t_a, t_b, t_e;
-		begin
-			op = t_op;
-			srcA = t_a;
-			srcB = t_b;
-			#1
-			$write("ALU Test: %b %8s %b = %b ", t_a, op.name, t_b, result);
-			if (result == t_e) $display("(correct)");
-			else $display("(expected %b)", t_e); 
-			assert(result == t_e);	
-		end		
+		input e_c, e_o;
+		testprint(t_op, t_a, t_b, t_e, e_c, e_o, 1);
 	endtask
 
 	initial begin
 		sign = 0;
 		cin = 0;
-		test(ALU_ADD, 120, 100, 220);
-		test(ALU_SUB, 120, 100, 20);
-		testb(ALU_AND, 120, 100, 96);
-		testb(ALU_NAND, 100, 120, -97);
-		testb(ALU_OR, 100, 120, 124);
-		testb(ALU_NOR, 100, 120, -125);
-		testb(ALU_XOR, 100, 120, 28);
-		testb(ALU_XNOR, 100, 120, -29);
-		testb(ALU_SL, 8'b1111_0111, 2, 8'b1101_1100);
-		testb(ALU_SR, 8'b1110_1111, 2, 8'b0011_1011);
+		test(ALU_ADD, 120, 100, 220, 0, 0);
+		test(ALU_ADD, 255, 255, 254, 1, 0);
+		test(ALU_SUB, 120, 100, 20, 0, 0);
+		test(ALU_SUB, 0, 100, -100, 1, 0); // FIXME: When unsigned probably want underflow flag on.
+		testb(ALU_AND, 120, 100, 96, 0, 0);
+		testb(ALU_NAND, 100, 120, -97, 0, 0);
+		testb(ALU_OR, 100, 120, 124, 0, 0);
+		testb(ALU_NOR, 100, 120, -125, 0, 0);
+		testb(ALU_XOR, 100, 120, 28, 0, 0);
+		testb(ALU_XNOR, 100, 120, -29, 0, 0);
+		testb(ALU_SL, 8'b1111_0111, 2, 8'b1101_1100, 0, 0);
+		testb(ALU_SR, 8'b1110_1111, 2, 8'b0011_1011, 0, 0);
 		sign = 1;
 		$display("ALU Settings: sign = 1");
 		
-		testb(ALU_SR, 8'b1000_0100, 2, 8'b1110_0001);
-		testb(ALU_SR, 8'b0000_0100, 2, 8'b0000_0001);
-		test(ALU_ADD, -10, 20, 10);
-		test(ALU_SUB, -10, -20, 10);
+		testb(ALU_SR, 8'b1000_0100, 2, 8'b1110_0001, 0, 0);
+		testb(ALU_SR, 8'b0000_0100, 2, 8'b0000_0001, 0, 0);
+		test(ALU_ADD, -10, 20, 10, 0, 0);
+		test(ALU_ADD, -10, -20, -30, 0, 0);
+		test(ALU_SUB, -10, -20, 10, 0, 0);
+		test(ALU_SUB, -10, 20, -30, 0, 0);
+		testb(ALU_SUB, -10, 20, -30, 0, 0);
 		
-		testb(ALU_ROR, 8'b1100_0000, 0, 8'b1000_0001);
-		testb(ALU_ROL, 8'b0000_0011, 0, 8'b1000_0001);
-		test(ALU_MUL, 5, 8, 40);
-		test(ALU_DIV, 64, 4, 16);
-		test(ALU_DIV, 65, 4, 16);
-		test(ALU_MOD, 66, 4, 2);
-		test(ALU_MOD, 65, 4, 1);
-		test(ALU_MOD, 64, 4, 0);
+		testb(ALU_ROR, 8'b1100_0000, 0, 8'b1000_0001, 0, 0);
+		testb(ALU_ROL, 8'b0000_0011, 0, 8'b1000_0001, 0, 0);
+		test(ALU_MUL, 5, 8, 40, 0, 0);
+		testb(ALU_MUL, -5, 8, -40, 0, 0);
+		test(ALU_DIV, 64, 4, 16, 0, 0);
+		test(ALU_DIV, 64, -4, -16, 0, 0);
+		test(ALU_DIV, 65, 4, 16, 0, 0);
+		test(ALU_MOD, 66, 4, 2, 0, 0);
+		test(ALU_MOD, 65, 4, 1, 0, 0);
+		test(ALU_MOD, 64, 4, 0, 0, 0);
+		#10
 		$stop;
 	end
 

+ 131 - 0
src/blocks/fifo.v

@@ -0,0 +1,131 @@
+/*
+ * This is a 2 clock fifo used for transferring data between
+ * clock domains. 
+ * 
+ * I assume here that the output (read) clock is >5X slower than the
+ * input (write) clock.
+ *
+ * Also, the fifo is just 1 word deep. 
+ *
+ * Changes
+ *  - 2015-07-03   issue when writing from low speed clock, empty_n goes
+ *                 high and stays high.  The reader side will see and read, but
+ *                 after complete empty_n is still high.  It will continue
+ *                 to read until empty_n is lowered based on the write side
+ *                 clock.
+ *                 The empty_n should go low once the reader reads.
+ *
+ */
+
+
+// Taken from: https://github.com/stffrdhrn/sdram-controller
+
+
+module fifo (
+  // Write side
+  wr_clk,
+  wr_data, 
+  wr,
+  full,   // means don't write any more
+  
+  // Read side
+  rd_data,
+  rd_clk,
+  rd,
+  empty_n, // also means we can read
+  
+  rst_n
+);
+
+parameter BUS_WIDTH = 16;
+
+input [BUS_WIDTH-1:0]  wr_data;
+input                  wr_clk;
+input                  wr;
+output                 full;      // Low-Means in side can write
+
+output [BUS_WIDTH-1:0] rd_data; 
+input                  rd_clk;
+input                  rd;
+output                 empty_n;   // High-Means out side can read
+
+input                  rst_n;
+
+reg [BUS_WIDTH-1:0]    wr_data_r;
+reg [BUS_WIDTH-1:0]    rd_data;
+
+/* 
+ * these reg sets span accross 2 clock domtains
+ *   CLK WR                    | CLK RD
+ *  [wr_r] ------------------> | -> [wr_syn1] -> [wr_syn2] -\
+ *  <- [wr_ack2] <- [wr_ack1]  | ---------------------------/
+ *    ^^^^^^^^^^               |  
+ *  Set wr_r when we get a wr  |  increment counter when we get
+ *  Clr wr when we get wr_ack2 |  wr_syn2, and syncronize data
+ * 
+ */
+reg                    wr_r, wr_syn1, wr_syn2, wr_ack1, wr_ack2;
+reg                    rd_r, rd_syn1, rd_syn2, rd_ack1, rd_ack2;
+reg                    wr_fifo_cnt;
+reg                    rd_fifo_cnt;
+
+assign full = wr_fifo_cnt == 1'b1;
+assign empty_n = rd_fifo_cnt == 1'b1;
+
+always @ (posedge rd_clk)
+  if (~rst_n)
+    begin
+       rd_fifo_cnt <= 1'b0;
+       {rd_ack2, rd_ack1} <= 2'b00; 
+       {wr_syn2, wr_syn1} <= 2'b00; 
+    end
+  else
+    begin
+      
+      {rd_ack2, rd_ack1} <= {rd_ack1, rd_syn2}; 
+      {wr_syn2, wr_syn1} <= {wr_syn1, wr_r}; 
+      
+      if (rd)
+        rd_r <= 1'b1;
+      else if (rd_ack2)
+        rd_r <= 1'b0;
+      
+      if (rd)
+        rd_fifo_cnt <= 1'b0;
+      if ({wr_syn2, wr_syn1} == 2'b01) // if we want to just do increment 1 time, we can check posedge
+        rd_fifo_cnt <= 1'b1;
+      
+      if (wr_syn2)
+        rd_data <= wr_data_r;
+    end
+    
+always @ (posedge wr_clk)
+ if (~rst_n)
+   begin
+      wr_fifo_cnt <= 1'b0;
+      {rd_syn2, rd_syn1} <= 2'b00;
+      {wr_ack2, wr_ack1} <= 2'b00;
+   end
+ else
+   begin
+     {wr_ack2, wr_ack1} <= {wr_ack1, wr_syn2};   
+     {rd_syn2, rd_syn1} <= {rd_syn1, rd_r};
+   
+     if (wr)
+       wr_r <= 1'b1;
+     if (wr_ack2)
+       wr_r <= 1'b0;
+       
+     if (wr)
+       wr_fifo_cnt <= 1'b1;
+     if ({rd_syn2, rd_syn1} == 2'b01)
+       wr_fifo_cnt <= 1'b0;
+       
+     // register write data on write
+     if (wr)
+       wr_data_r <= wr_data;
+
+   end
+
+
+endmodule

+ 7 - 6
src/blocks/instr_mem.sv

@@ -1,12 +1,13 @@
-import project_pkg::*;
-
 module instr_mem(addr, instr, imm);
 	parameter IMEM_FILE = "";
-	input  word addr;
-	output word	imm;
-	output word	instr;
+	parameter WIDTH=8, LENGTH=256;
+	localparam ADDR_WIDTH = $clog2(LENGTH);
+
+	input  [ADDR_WIDTH-1:0] addr;
+	output [WIDTH-1:0]	imm;
+	output [WIDTH-1:0]	instr;
 	
-	logic [word_size-1:0] rom [rom_size-1:0];
+	logic [WIDTH-1:0] rom [LENGTH-1:0];
 	initial $readmemh(IMEM_FILE, rom);
 	initial begin
 		 $display("Instruction ROM dump");

+ 9 - 7
src/blocks/memory.sv

@@ -1,12 +1,14 @@
-import project_pkg::*;
+module memory(clk, we, a, wd, rd);
 
-module memory(
-		input 	logic 	clk, we,
-		input 	word 	a, wd, 
-		output 	word 	rd
-	);	
+	parameter WIDTH=8, LENGTH=256;	
+	localparam ADDR_WIDTH = $clog2(LENGTH);
 	
-	logic [word_size-1:0]memory[mem_size-1:0];
+	input  	clk, we;
+	input 	[WIDTH-1:0]	wd;
+	input 	[ADDR_WIDTH-1:0] a;
+	output 	[WIDTH-1:0]	rd;
+	
+	logic [WIDTH-1:0]memory[LENGTH-1:0];
 	assign rd = memory[a];
 	
 	always_ff@(posedge clk) if(we) memory[a] <= wd;

+ 12 - 9
src/blocks/reg_file.sv

@@ -1,16 +1,19 @@
-import project_pkg::*;
-
 module reg_file(clk, rst, rd_addr1, rd_addr2, rd_data1, rd_data2, wr_addr, wr_data, wr_en);
-	input logic  clk, rst, wr_en;
-	input  e_reg rd_addr1, rd_addr2, wr_addr;
-	input  word		wr_data;
-	output word 	rd_data1;
-	output word 	rd_data2;
+	parameter WIDTH=8, LENGTH=4;
+	localparam ADDR_WIDTH = $clog2(LENGTH);
+
+	input  clk, rst, wr_en;
+	input  [ADDR_WIDTH-1:0] rd_addr1, rd_addr2, wr_addr;
+	input  [WIDTH-1:0] wr_data;
+	output [WIDTH-1:0] rd_data1;
+	output [WIDTH-1:0] rd_data2;
+
+	
 	
-	logic [word_size-1:0] registry [reg_size-1:0];
+	logic [WIDTH-1:0] registry [LENGTH-1:0];
 	
 	always_ff@(posedge clk) begin
-	  	if(rst) for(int i=0;i<reg_size;i++) registry[i] <= '0;
+	  	if(rst) for(int i=0;i<LENGTH;i++) registry[i] <= '0;
 		else if(wr_en) registry[wr_addr] <= wr_data;
 	end
 	

+ 0 - 0
src/blocks/reg_file_tb.sv


+ 419 - 0
src/blocks/sdram_control.sv

@@ -0,0 +1,419 @@
+/**
+ * simple controller for ISSI IS42S16160G-7 SDRAM found in De0 Nano
+ *  16Mbit x 16 data bit bus (32 megabytes)
+ *  Default options
+ *    133Mhz
+ *    CAS 3
+ *
+ *  Very simple host interface
+ *     * No burst support
+ *     * haddr - address for reading and wriging 16 bits of data
+ *     * data_input - data for writing, latched in when wr_enable is highz0
+ *     * data_output - data for reading, comes available sometime
+ *       *few clocks* after rd_enable and address is presented on bus
+ *     * rst_n - start init ram process
+ *     * rd_enable - read enable, on clk posedge haddr will be latched in,
+ *       after *few clocks* data will be available on the data_output port
+ *     * wr_enable - write enable, on clk posedge haddr and data_input will
+ *       be latched in, after *few clocks* data will be written to sdram
+ *
+ * Theory
+ *  This simple host interface has a busy signal to tell you when you are
+ *  not able to issue commands.
+ */
+
+// Taken from: https://github.com/stffrdhrn/sdram-controller
+
+module sdram_controller (
+    /* HOST INTERFACE */
+    wr_addr,
+    wr_data,
+    wr_enable,
+
+    rd_addr,
+    rd_data,
+    rd_ready,
+    rd_enable,
+
+    busy, rst_n, clk,
+
+    /* SDRAM SIDE */
+    addr, bank_addr, data, clock_enable, cs_n, ras_n, cas_n, we_n,
+    data_mask_low, data_mask_high
+);
+
+/* Internal Parameters */
+parameter ROW_WIDTH = 13;
+parameter COL_WIDTH = 9;
+parameter BANK_WIDTH = 2;
+
+parameter SDRADDR_WIDTH = ROW_WIDTH > COL_WIDTH ? ROW_WIDTH : COL_WIDTH;
+parameter HADDR_WIDTH = BANK_WIDTH + ROW_WIDTH + COL_WIDTH;
+
+parameter CLK_FREQUENCY = 133;  // Mhz
+parameter REFRESH_TIME =  32;   // ms     (how often we need to refresh)
+parameter REFRESH_COUNT = 8192; // cycles (how many refreshes required per refresh time)
+
+// clk / refresh =  clk / sec
+//                , sec / refbatch
+//                , ref / refbatch
+localparam CYCLES_BETWEEN_REFRESH = ( CLK_FREQUENCY
+                                      * 1_000
+                                      * REFRESH_TIME
+                                    ) / REFRESH_COUNT;
+
+// STATES - State
+localparam IDLE      = 5'b00000;
+
+localparam INIT_NOP1 = 5'b01000,
+           INIT_PRE1 = 5'b01001,
+           INIT_NOP1_1=5'b00101,
+           INIT_REF1 = 5'b01010,
+           INIT_NOP2 = 5'b01011,
+           INIT_REF2 = 5'b01100,
+           INIT_NOP3 = 5'b01101,
+           INIT_LOAD = 5'b01110,
+           INIT_NOP4 = 5'b01111;
+
+localparam REF_PRE  =  5'b00001,
+           REF_NOP1 =  5'b00010,
+           REF_REF  =  5'b00011,
+           REF_NOP2 =  5'b00100;
+
+localparam READ_ACT  = 5'b10000,
+           READ_NOP1 = 5'b10001,
+           READ_CAS  = 5'b10010,
+           READ_NOP2 = 5'b10011,
+           READ_READ = 5'b10100;
+
+localparam WRIT_ACT  = 5'b11000,
+           WRIT_NOP1 = 5'b11001,
+           WRIT_CAS  = 5'b11010,
+           WRIT_NOP2 = 5'b11011;
+
+// Commands              CCRCWBBA
+//                       ESSSE100
+localparam CMD_PALL = 8'b10010001,
+           CMD_REF  = 8'b10001000,
+           CMD_NOP  = 8'b10111000,
+           CMD_MRS  = 8'b1000000x,
+           CMD_BACT = 8'b10011xxx,
+           CMD_READ = 8'b10101xx1,
+           CMD_WRIT = 8'b10100xx1;
+
+/* Interface Definition */
+/* HOST INTERFACE */
+input  [HADDR_WIDTH-1:0]   wr_addr;
+input  [15:0]              wr_data;
+input                      wr_enable;
+
+input  [HADDR_WIDTH-1:0]   rd_addr;
+output [15:0]              rd_data;
+input                      rd_enable;
+output                     rd_ready;
+
+output                     busy;
+input                      rst_n;
+input                      clk;
+
+/* SDRAM SIDE */
+output [SDRADDR_WIDTH-1:0] addr;
+output [BANK_WIDTH-1:0]    bank_addr;
+inout  [15:0]              data;
+output                     clock_enable;
+output                     cs_n;
+output                     ras_n;
+output                     cas_n;
+output                     we_n;
+output                     data_mask_low;
+output                     data_mask_high;
+
+/* I/O Registers */
+
+reg  [HADDR_WIDTH-1:0]   haddr_r;
+reg  [15:0]              wr_data_r;
+reg  [15:0]              rd_data_r;
+reg                      busy;
+reg                      data_mask_low_r;
+reg                      data_mask_high_r;
+reg [SDRADDR_WIDTH-1:0]  addr_r;
+reg [BANK_WIDTH-1:0]     bank_addr_r;
+reg                      rd_ready_r;
+
+wire [15:0]              data_output;
+wire                     data_mask_low, data_mask_high;
+
+assign data_mask_high = data_mask_high_r;
+assign data_mask_low  = data_mask_low_r;
+assign rd_data        = rd_data_r;
+
+/* Internal Wiring */
+reg [3:0] state_cnt;
+reg [9:0] refresh_cnt;
+
+reg [7:0] command;
+reg [4:0] state;
+
+// TODO output addr[6:4] when programming mode register
+
+reg [7:0] command_nxt;
+reg [3:0] state_cnt_nxt;
+reg [4:0] next;
+
+assign {clock_enable, cs_n, ras_n, cas_n, we_n} = command[7:3];
+// state[4] will be set if mode is read/write
+assign bank_addr      = (state[4]) ? bank_addr_r : command[2:1];
+assign addr           = (state[4] | state == INIT_LOAD) ? addr_r : { {SDRADDR_WIDTH-11{1'b0}}, command[0], 10'd0 };
+
+assign data = (state == WRIT_CAS) ? wr_data_r : 16'bz;
+assign rd_ready = rd_ready_r;
+
+// HOST INTERFACE
+// all registered on posedge
+always @ (posedge clk)
+  if (~rst_n)
+    begin
+    state <= INIT_NOP1;
+    command <= CMD_NOP;
+    state_cnt <= 4'hf;
+
+    haddr_r <= {HADDR_WIDTH{1'b0}};
+    wr_data_r <= 16'b0;
+    rd_data_r <= 16'b0;
+    busy <= 1'b0;
+    end
+  else
+    begin
+
+    state <= next;
+    command <= command_nxt;
+
+    if (!state_cnt)
+      state_cnt <= state_cnt_nxt;
+    else
+      state_cnt <= state_cnt - 1'b1;
+
+    if (wr_enable)
+      wr_data_r <= wr_data;
+
+    if (state == READ_READ)
+      begin
+      rd_data_r <= data;
+      rd_ready_r <= 1'b1;
+      end
+    else
+      rd_ready_r <= 1'b0;
+
+    busy <= state[4];
+
+    if (rd_enable)
+      haddr_r <= rd_addr;
+    else if (wr_enable)
+      haddr_r <= wr_addr;
+
+    end
+
+// Handle refresh counter
+always @ (posedge clk)
+ if (~rst_n)
+   refresh_cnt <= 10'b0;
+ else
+   if (state == REF_NOP2)
+     refresh_cnt <= 10'b0;
+   else
+     refresh_cnt <= refresh_cnt + 1'b1;
+
+
+/* Handle logic for sending addresses to SDRAM based on current state*/
+always @*
+begin
+    if (state[4])
+      {data_mask_low_r, data_mask_high_r} = 2'b00;
+    else
+      {data_mask_low_r, data_mask_high_r} = 2'b11;
+
+   bank_addr_r = 2'b00;
+   addr_r = {SDRADDR_WIDTH{1'b0}};
+
+   if (state == READ_ACT | state == WRIT_ACT)
+     begin
+     bank_addr_r = haddr_r[HADDR_WIDTH-1:HADDR_WIDTH-(BANK_WIDTH)];
+     addr_r = haddr_r[HADDR_WIDTH-(BANK_WIDTH+1):HADDR_WIDTH-(BANK_WIDTH+ROW_WIDTH)];
+     end
+   else if (state == READ_CAS | state == WRIT_CAS)
+     begin
+     // Send Column Address
+     // Set bank to bank to precharge
+     bank_addr_r = haddr_r[HADDR_WIDTH-1:HADDR_WIDTH-(BANK_WIDTH)];
+
+     // Examples for math
+     //               BANK  ROW    COL
+     // HADDR_WIDTH   2 +   13 +   9   = 24
+     // SDRADDR_WIDTH 13
+
+     // Set CAS address to:
+     //   0s,
+     //   1 (A10 is always for auto precharge),
+     //   0s,
+     //   column address
+     addr_r = {
+               {SDRADDR_WIDTH-(11){1'b0}},
+               1'b1,                       /* A10 */
+               {10-COL_WIDTH{1'b0}},
+               haddr_r[COL_WIDTH-1:0]
+              };
+     end
+   else if (state == INIT_LOAD)
+     begin
+     // Program mode register during load cycle
+     //                                       B  C  SB
+     //                                       R  A  EUR
+     //                                       S  S-3Q ST
+     //                                       T  654L210
+     addr_r = {{SDRADDR_WIDTH-10{1'b0}}, 10'b1000110000};
+     end
+end
+
+// Next state logic
+always @*
+begin
+   state_cnt_nxt = 4'd0;
+   command_nxt = CMD_NOP;
+   if (state == IDLE)
+        // Monitor for refresh or hold
+        if (refresh_cnt >= CYCLES_BETWEEN_REFRESH)
+          begin
+          next = REF_PRE;
+          command_nxt = CMD_PALL;
+          end
+        else if (rd_enable)
+          begin
+          next = READ_ACT;
+          command_nxt = CMD_BACT;
+          end
+        else if (wr_enable)
+          begin
+          next = WRIT_ACT;
+          command_nxt = CMD_BACT;
+          end
+        else
+          begin
+          // HOLD
+          next = IDLE;
+          end
+    else
+      if (!state_cnt)
+        case (state)
+          // INIT ENGINE
+          INIT_NOP1:
+            begin
+            next = INIT_PRE1;
+            command_nxt = CMD_PALL;
+            end
+          INIT_PRE1:
+            begin
+            next = INIT_NOP1_1;
+            end
+          INIT_NOP1_1:
+            begin
+            next = INIT_REF1;
+            command_nxt = CMD_REF;
+            end
+          INIT_REF1:
+            begin
+            next = INIT_NOP2;
+            state_cnt_nxt = 4'd7;
+            end
+          INIT_NOP2:
+            begin
+            next = INIT_REF2;
+            command_nxt = CMD_REF;
+            end
+          INIT_REF2:
+            begin
+            next = INIT_NOP3;
+            state_cnt_nxt = 4'd7;
+            end
+          INIT_NOP3:
+            begin
+            next = INIT_LOAD;
+            command_nxt = CMD_MRS;
+            end
+          INIT_LOAD:
+            begin
+            next = INIT_NOP4;
+            state_cnt_nxt = 4'd1;
+            end
+          // INIT_NOP4: default - IDLE
+
+          // REFRESH
+          REF_PRE:
+            begin
+            next = REF_NOP1;
+            end
+          REF_NOP1:
+            begin
+            next = REF_REF;
+            command_nxt = CMD_REF;
+            end
+          REF_REF:
+            begin
+            next = REF_NOP2;
+            state_cnt_nxt = 4'd7;
+            end
+          // REF_NOP2: default - IDLE
+
+          // WRITE
+          WRIT_ACT:
+            begin
+            next = WRIT_NOP1;
+            state_cnt_nxt = 4'd1;
+            end
+          WRIT_NOP1:
+            begin
+            next = WRIT_CAS;
+            command_nxt = CMD_WRIT;
+            end
+          WRIT_CAS:
+            begin
+            next = WRIT_NOP2;
+            state_cnt_nxt = 4'd1;
+            end
+          // WRIT_NOP2: default - IDLE
+
+          // READ
+          READ_ACT:
+            begin
+            next = READ_NOP1;
+            state_cnt_nxt = 4'd1;
+            end
+          READ_NOP1:
+            begin
+            next = READ_CAS;
+            command_nxt = CMD_READ;
+            end
+          READ_CAS:
+            begin
+            next = READ_NOP2;
+            state_cnt_nxt = 4'd1;
+            end
+          READ_NOP2:
+            begin
+            next = READ_READ;
+            end
+          // READ_READ: default - IDLE
+
+          default:
+            begin
+            next = IDLE;
+            end
+          endcase
+      else
+        begin
+        // Counter Not Reached - HOLD
+        next = state;
+        command_nxt = command;
+        end
+end
+
+endmodule

+ 245 - 0
src/project.sv

@@ -0,0 +1,245 @@
+interface processor_port(
+	input clk, rst,	interrupt,
+
+	// RAM
+	output [23:0]	ram_addr,
+	output [15:0] 	ram_wr_data,
+	input  [15:0] 	ram_rd_data,
+	output 			ram_wr_en,
+	output			ram_rd_en,
+	input			ram_busy,
+	input			ram_rd_ready,
+	input			ram_rd_ack,
+
+	// COM
+	output [7:0]	com_addr,
+	output [7:0]	com_wr,
+	input  [7:0]	com_rd
+	);
+
+endinterface
+
+module com_block(
+	input clk, rst,
+	// Communication to processor
+	input  [7:0]	addr,
+	input  [7:0]	wr_data,
+	output [7:0]	rd_data,
+
+	// IO
+	output [7:0]	leds,
+	input  [3:0]	switches,
+	output 			uart0_tx,
+	input 			uart0_rx
+);
+
+	/* UART */
+	reg [7:0] uart0_reg;
+	reg uart0_transmit;
+	wire [7:0] tx_byte, rx_byte;
+	// Clock divide = 1e6 / (9600 * 4)
+	uart#(.CLOCK_DIVIDE(26)) uart0(
+			.clk(clk), 
+			.rst(rst), 
+			.rx(uart0_rx),
+			.tx(uart0_tx),
+			.tx_byte(tx_byte),
+			.rx_byte(rx_byte),
+			.received(uart0_reg[0]),
+			.is_receiving(uart0_reg[1]),
+			.is_transmitting(uart0_reg[2]),
+			.transmit(uart0_transmit)
+	);
+	
+endmodule
+
+interface sdram_ctl_bus;
+	wire [23:0]	ram_addr;
+	wire [15:0] ram_wr_data;
+	wire [15:0] ram_rd_data;
+	wire 		ram_wr_en;
+	wire 		ram_rd_en;
+	wire 		ram_busy;
+	wire 		ram_rd_ready;
+	wire 		ram_rd_ack;
+	
+	modport out(
+		output	ram_addr,
+		output	ram_wr_data,
+		input 	ram_rd_data,
+		output	ram_wr_en,
+		output	ram_rd_en,
+		input	ram_busy,
+		input	ram_rd_ready,
+		input	ram_rd_ack
+	);
+	
+	modport in(
+		input	ram_addr,
+		input	ram_wr_data,
+		output 	ram_rd_data,
+		input	ram_wr_en,
+		input	ram_rd_en,
+		output	ram_busy,
+		output	ram_rd_ready,
+		output	ram_rd_ack
+	);
+endinterface
+
+interface sdram_io_bus(
+	inout  [15:0]	DRAM_DQ,	// Data
+	output [12:0] 	DRAM_ADDR,	// Address
+	output [1:0]	DRAM_DQM,	// Byte Data Mask
+	output    		DRAM_CLK,	// Clock
+	output    		DRAM_CKE,	// Clock Enable
+	output    		DRAM_WE_N,	// Write Enable
+	output    		DRAM_CAS_N, // Column Address Strobe
+	output    		DRAM_RAS_N, // Row Address Strobe
+	output    		DRAM_CS_N,	// Chip Select
+	output [1:0] 	DRAM_BA		// Bank Address
+	);
+//	
+//	modport out (
+//		inout  DRAM_DQ,	
+//		output DRAM_ADDR,	
+//		output DRAM_DQM,	
+//		output DRAM_CLK,	
+//		output DRAM_CKE,	
+//		output DRAM_WE_N,	
+//		output DRAM_CAS_N, 
+//		output DRAM_RAS_N, 
+//		output DRAM_CS_N,	
+//		output DRAM_BA			
+//	);
+endinterface
+
+module sdram_block(
+	input mclk, fclk, rst,
+
+	// SDRAM Control
+	input [23:0]	ram_addr,
+	input [15:0] 	ram_wr_data,
+	output  [15:0] 	ram_rd_data,
+	input 			ram_wr_en,
+	input			ram_rd_en,
+	output			ram_busy,
+	output			ram_rd_ready,
+	output			ram_rd_ack,
+	
+
+	// SDRAM I/O
+	inout  [15:0]	DRAM_DQ,	// Data
+	output [12:0] 	DRAM_ADDR,	// Address
+	output [1:0]	DRAM_DQM,	// Byte Data Mask
+	output			DRAM_CLK,	// Clock
+	output			DRAM_CKE,	// Clock Enable
+	output			DRAM_WE_N,	// Write Enable
+	output			DRAM_CAS_N, // Column Address Strobe
+	output			DRAM_RAS_N, // Row Address Strobe
+	output			DRAM_CS_N,	// Chip Select
+	output [1:0] 	DRAM_BA		// Bank Address
+);
+	/* SDRAM */
+
+	// 1 MHz side wires
+	wire [39:0] wr_fifo;// Address 24-bit and 16-bit Data
+	wire wr_enable;		// wr_enable ] <-> [ wr 	: wr_enable to push fifo
+	wire wr_full;		// wr_full   ] <-> [ full 	: signal that we are full
+	wire rd_enable;		// rd_enable - wr 			: rd_enable to push rd addr to fifo
+	wire rdaddr_full;	// rdaddr_full - full 		: signal we cannot read more
+	wire [15:0] rddo_fifo;
+	wire ctrl_rd_ready;	// wr - rd_ready 			: push data from dram to fifo
+
+	// 100MHz side wires
+	wire [39:0] wro_fifo;
+	wire ctrl_busy;       	// rd ] <-> [ busy 		: pop fifo when ctrl not busy
+	wire ctrl_wr_enable;  	// empty_n - wr_enable 	: signal ctrl data is ready
+	wire [23:0] rdao_fifo;
+	wire ctrl_rd_enable;	// empty_n - rd_enable 	: signal ctrl addr ready
+	wire [15:0] rddata_fifo;
+	wire rd_ready;   		// rd_ready - empty_n 	: signal interface data ready
+	wire rd_ack;     		// rd_ack - rd     		: pop fifo after data read
+
+	wire busy;				// RAM is busy because RW FIFO is full
+	assign busy = wr_full | rdaddr_full;
+
+
+	fifo #(.BUS_WIDTH(40)) dram_wr_fifo (
+	    .wr_clk        (mclk),
+	    .rd_clk        (fclk),
+	    .wr_data       (wr_fifo),
+	    .rd_data       (wro_fifo),
+	    .rd            (ctrl_busy),
+	    .wr            (wr_enable),
+	    .full          (wr_full),
+	    .empty_n       (ctrl_wr_enable),
+	    .rst_n         (rst)
+	);
+	
+	fifo #(.BUS_WIDTH(24)) dram_rd_addr_fifo (
+	    .wr_clk        (mclk),
+	    .rd_clk        (fclk),
+	    .wr_data       (wr_fifo[39:16]),
+	    .rd_data       (rdao_fifo),
+	    .rd            (ctrl_busy),
+	    .wr            (rd_enable),
+	    .full          (rdaddr_full),
+	    .empty_n       (ctrl_rd_enable),
+	    .rst_n         (rst)
+	);
+	
+	fifo #(.BUS_WIDTH(16)) dram_rd_data_fifo (
+	    .wr_clk        (fclk),
+	    .rd_clk        (mclk),
+	    .wr_data       (rddo_fifo),
+	    .rd_data       (rddata_fifo),
+	    .rd            (rd_ack),
+	    .wr            (ctrl_rd_ready),
+	    .empty_n       (rd_ready),
+	    .rst_n         (rst)
+	);
+	
+	// Setting SDRAM clock to 100MHz
+	assign DRAM_CLK = fclk;
+
+	sdram_controller sdram_control0 (
+	    // HOST INTERFACE
+	    .wr_addr       (wro_fifo[39:16]),
+	    .wr_data       (wro_fifo[15:0]),
+	    .wr_enable     (ctrl_wr_enable), 
+	
+	    .rd_addr       (rdao_fifo), 
+	    .rd_data       (rddo_fifo),
+	    .rd_ready      (ctrl_rd_ready),
+	    .rd_enable     (ctrl_rd_enable),
+	    
+	    .busy          (ctrl_busy),
+	    .rst_n         (rst),
+	    .clk           (fclk),
+	
+	    // SDRAM SIDE
+	    .addr          (DRAM_ADDR),
+	    .bank_addr     (DRAM_BA),
+	    .data          (DRAM_DQ),
+	    .clock_enable  (DRAM_CKE),
+	    .cs_n          (DRAM_CS_N),
+	    .ras_n         (DRAM_RAS_N),
+	    .cas_n         (DRAM_CAS_N),
+	    .we_n          (DRAM_WE_N),
+		.data_mask_low (DRAM_DQM[0]),
+		.data_mask_high(DRAM_DQM[1])
+	);
+
+	// Assign inputs	
+	assign wr_fifo[39:16] 	= ram_addr;
+    assign wr_fifo[15:0] 	= ram_wr_data;
+	assign wr_enable 		= ram_wr_en;
+	assign rd_enable 		= ram_rd_en;
+	
+	// Assign outputs
+	assign ram_rd_data 		= rddata_fifo;
+ 	assign ram_busy 		= busy;
+	assign ram_rd_ready 	= rd_ready;
+	assign ram_rd_ack 		= rd_ack;
+ 		
+endmodule

+ 4 - 2
src/risc/controller.sv

@@ -1,4 +1,5 @@
-import project_pkg::*;
+import risc_pkg::*;
+import alu_pkg::*;
 
 module controller(instr, zero, alu_op, alu_ex, mem_wr, reg_wr, 
 		pc_src, rimm, alu_src, mem_to_reg, instr_op, rd, rs, sp_wr, mem_sp);
@@ -17,7 +18,8 @@ module controller(instr, zero, alu_op, alu_ex, mem_wr, reg_wr,
 	assign rs 			= e_reg'(instr[1:0]);
 	
 	e_alu_op alu_subsel;
-	assign alu_subsel = (instr_op == JEQ) ? ALU_SUB : ALU_CPY;
+	//assign alu_subsel = (instr_op == JEQ) ? ALU_SUB : ALU_CPY;
+	assign alu_subsel = (instr_op == JEQ) ? ALU_SUB: ALU_ADD;
 	assign alu_op = instr_op[3] ? alu_subsel : e_alu_op'(instr_op[2:0]);
 	assign reg_wr = ~instr_op[3] | instr_op == LW | instr_op == POP; 
 	

+ 5 - 4
src/risc/cpu.sv

@@ -1,7 +1,8 @@
-`timescale 1ns / 1ps
-import project_pkg::*;
+`timescale 1ns / 100ps
+import risc_pkg::*;
+import alu_pkg::*;
 
-module cpu(clk, rst, instr, imm, pc, mem_addr, mem_wr_en, mem_wr_data, mem_rd_data);
+module risc8_cpu(clk, rst, instr, imm, pc, mem_addr, mem_wr_en, mem_wr_data, mem_rd_data);
 	input logic clk, rst;
 	input word instr, imm, mem_rd_data;
 	output logic mem_wr_en;
@@ -20,7 +21,7 @@ module cpu(clk, rst, instr, imm, pc, mem_addr, mem_wr_en, mem_wr_data, mem_rd_da
 	datapath DPATH(clk, rst, rd, rs, imm, alu_op, alu_ex, reg_wr, pc_src, rimm, alu_src, mem_to_reg, pc, mem_addr, mem_rd_data, alu_zero, mem_wr_data, sp_wr, mem_sp);	
 endmodule
 
-module cpu_tb;
+module risc8_cpu_tb;
 	logic clk, rst, mem_wr; 
 	word pc, instr, imm, mem_addr, mem_data, mem_rd_data;	
 	cpu CPU(clk, rst, instr, imm, pc, mem_addr, mem_wr, mem_data, mem_rd_data);

+ 11 - 3
src/risc/datapath.sv

@@ -1,4 +1,5 @@
-import project_pkg::*;
+import risc_pkg::*;
+import alu_pkg::*;
 
 module datapath(clk, rst, rd, rs, imm, alu_op, alu_ex, reg_wr, pc_src, 
 		rimm, alu_src, mem_to_reg, pc, alu_out, mem_data, alu_zero, 
@@ -33,7 +34,14 @@ module datapath(clk, rst, rd, rs, imm, alu_op, alu_ex, reg_wr, pc_src,
 	word sp_sel;
 	assign sp_sel = (mem_sp) ? sp_next : sp;
 	assign alu_out = (sp_wr) ? sp_sel : alu_result;
-	alu ALU(alu_op, alu_ex, alu_srcA, alu_srcB, alu_result, alu_zero);	
+	alu alu0(
+		.a(alu_srcA),
+		.b(alu_srcB),
+		.op(alu_op),
+		.r(alu_result),
+		.zero(alu_zero)
+	);
+	//alu_op, alu_ex, alu_srcA, alu_srcB, alu_result, alu_zero);	
 	// Program counter
 	word pcn; 	// PC next
 	word pcj;   // PC jump, +2 if imm used otherwise +1
@@ -75,7 +83,7 @@ module datapath_tb;
 		mem_to_reg = 0;
 		rs = ra;
 		rt = ra;
-		alu_op = ALU_CPY;
+		//alu_op = ALU_CPY;
 		imm = 8'h00;
 		mem_data = 8'h00;
 		#10ns;

+ 1 - 12
src/risc/general.sv

@@ -1,4 +1,4 @@
-package project_pkg;
+package risc_pkg;
 		
 	localparam word_size = 8;
 	localparam mem_size = 256;
@@ -38,17 +38,6 @@ package project_pkg;
 		POP =4'b1111   // Pop stack to $rd
 	} e_instr;
 
-	typedef enum logic [2:0] {
-		ALU_CPY = 3'b000, // TODO: Could be replaced by AEX_3
-		ALU_ADD = 3'b001,
-		ALU_SUB = 3'b010,
-		ALU_AND = 3'b011,
-		ALU_OR  = 3'b100,
-		ALU_XOR = 3'b101,
-		ALU_GT  = 3'b110,
-		ALU_EXT = 3'b111
-	} e_alu_op;
-
 	typedef enum logic [1:0] {
 		AEX_SHFL = 2'b00,
 		AEX_SHFR = 2'b01,

+ 0 - 51
src/risc/io_unit.sv

@@ -1,51 +0,0 @@
-import project_pkg::word;
-
-module io_unit(
-	input  logic clk, rx,
-	input  logic [3:0]switches,
-	input  logic [1:0]keys,
-	output logic tx,
-	output logic [7:0]leds
-	);
-	
-	logic transmit, received, is_receiving, is_transmitting, recv_error;
-	logic [7:0] tx_byte, rx_byte;
-	assign leds[0] = received;
-	assign leds[1] = is_receiving;
-	assign leds[2] = is_transmitting;
-	//assign leds[3] = recv_error;
-	//assign leds[6] = rx;
-	//assign leds[7] = tx;
-	logic clk_slow;
-
-	clk_div clk_div12(clk, rst, clk_slow);	
-	assign rst = ~keys[0];
-	//assign transmit = keys[1];
-	//assign tx_byte = rx_byte;
-
-	uart uart0(clk, rst, rx, tx, transmit, tx_byte, received, rx_byte, is_receiving, is_transmitting, );
-
-	//assign clk = keys[1];
-	logic mem_wr;
-	word pc, instr, imm, mem_addr, mem_data, mem_rd_data;
-	word ext_rd_data, rd_data;
-	cpu CPU(clk_slow, rst, instr, imm, pc, mem_addr, mem_wr, mem_data, rd_data);
-	// Instruction memory
-	instr_mem #("/home/min/devel/fpga/ucl_project_y3/memory/test.mem") IMEM(pc, instr, imm);
-	// System memory
-	memory RAM(clk, mem_wr, mem_addr, mem_data, mem_rd_data);
-	
-	assign ext_rd_data = '{0,0,0,0, 0,0,0,is_transmitting};
-	assign rd_data = (mem_addr == 8'hFF) ? ext_rd_data : mem_rd_data;
-
-	always_ff@(posedge clk_slow) begin
-			if(mem_wr & mem_addr == 8'hFF) begin
-				tx_byte <= mem_data;
-				transmit <= 1; 
-			end
-			else begin
-				transmit <= 0; 
-			end
-	end
-
-endmodule

+ 140 - 0
src/top.sv

@@ -0,0 +1,140 @@
+/*
+ * This is top level entity file.
+ * It includes all cpu external modules like UART
+ * and SDRAM controller. 
+*/
+module top(
+	input  			CLK50,		// Clock 50MHz
+
+	// Board connections
+	input  [3:0]	SWITCH,		// 4 Dip switches
+	input  [1:0]	KEY,		// 2 Keys
+	output [7:0]	LED,		// 8 LEDs
+
+	// UART
+	input  			RX,			// UART Receive
+	output 			TX,			// UART Transmit
+
+	// SDRAM
+	inout  [15:0]	DRAM_DQ,	// Data
+	output [12:0] 	DRAM_ADDR,	// Address
+	output [1:0]	DRAM_DQM,	// Byte Data Mask
+	output			DRAM_CLK,	// Clock
+	output			DRAM_CKE,	// Clock Enable
+	output			DRAM_WE_N,	// Write Enable
+	output			DRAM_CAS_N, // Column Address Strobe
+	output			DRAM_RAS_N, // Row Address Strobe
+	output			DRAM_CS_N,	// Chip Select
+	output [1:0] 	DRAM_BA		// Bank Address
+
+	);
+	
+	assign rst = ~KEY[0];
+	
+	/* Clocks */
+	wire mclk; // Master clock 		1MHz 		(for cpu)
+	wire fclk; // Fast clock 		100MHz 		(for sdram)
+	wire aclk; // Auxiliary clock 	32,768kHz 	(for timers)
+	
+	pll_clk pll_clk0 (
+			.inclk0(CLK50),
+			.areset(rst),
+			.c0(fclk),
+			.c1(mclk),
+			.c2(aclk)
+	);
+
+	wire [23:0]	ram_addr;
+    wire [15:0] ram_wr_data;
+    wire [15:0] ram_rd_data;
+    wire 		ram_wr_en;
+    wire		ram_rd_en;
+    wire  		ram_busy;
+	wire  		ram_rd_ready;
+	wire  		ram_rd_ack;
+
+	sdram_block sdram0(
+		.mclk(mclk), 
+		.fclk(fclk), 
+		.rst(rst), 
+		.ram_addr(ram_addr),
+		.ram_wr_data(ram_wr_data),
+		.ram_rd_data(ram_rd_data),
+		.ram_wr_en(ram_wr_en),
+		.ram_rd_en(ram_rd_en),
+		.ram_busy(ram_busy),
+		.ram_rd_ready(ram_rd_ready),
+		.ram_rd_ack(ram_rd_ack),
+		.DRAM_DQ(DRAM_DQ),	
+		.DRAM_ADDR(DRAM_ADDR),	
+		.DRAM_DQM(DRAM_DQM),	
+		.DRAM_CLK(DRAM_CLK),	
+		.DRAM_CKE(DRAM_CKE),	
+		.DRAM_WE_N(DRAM_WE_N),	
+		.DRAM_CAS_N(DRAM_CAS_N),
+		.DRAM_RAS_N(DRAM_RAS_N),
+		.DRAM_CS_N(DRAM_CS_N),	
+		.DRAM_BA(DRAM_BA)	
+	);
+
+
+	// Processor
+	wire interrupt;
+	assign interrupt = ~KEY[1];
+
+	processor_port cpu0 (
+		.clk(mclk),
+		.rst(rst),
+		.interrupt(interrupt),
+		.ram_addr(ram_addr),
+        .ram_wr_data(ram_wr_data),
+        .ram_rd_data(ram_rd_data),
+        .ram_wr_en(ram_wr_en),
+        .ram_rd_en(ram_rd_en),
+        .ram_busy(ram_busy),
+		.ram_rd_ready(ram_rd_ready),
+		.ram_rd_ack(ram_rd_ack),
+		.com_addr(com0_addr),
+		.com_wr(com0_wr),
+		.com_rd(com0_rd)
+	);
+
+	//Communication block
+	wire [7:0] com0_addr, com0_wr, com0_rd;
+
+	com_block com0 (
+			.clk(mclk),
+			.rst(rst),
+			.addr(com0_addr),
+			.wr_data(com0_wr),
+			.rd_data(com0_rd),
+			.leds(LED),
+			.switches(SWITCH),
+			.uart0_rx(RX),
+			.uart0_tx(TX)
+	);
+	//assign clk = keys[1];
+	//logic mem_wr;
+	//word pc, instr, imm, mem_addr, mem_data, mem_rd_data;
+	//word ext_rd_data, rd_data;
+	//cpu CPU(clk_slow, rst, instr, imm, pc, mem_addr, mem_wr, mem_data, rd_data);
+	// Instruction memory
+	//instr_mem #("/home/min/devel/fpga/ucl_project_y3/memory/test.mem") IMEM(pc, instr, imm);
+	// System memory
+	//memory RAM(clk, mem_wr, mem_addr, mem_data, mem_rd_data);
+	
+	//assign ext_rd_data = '{0,0,0,0, 0,0,0,is_transmitting};
+	//assign rd_data = (mem_addr == 8'hFF) ? ext_rd_data : mem_rd_data;
+
+	//always_ff@(posedge clk_slow) begin
+	//		if(mem_wr & mem_addr == 8'hFF) begin
+	//			tx_byte <= mem_data;
+	//			transmit <= 1; 
+	//		end
+	//		else begin
+	//			transmit <= 0; 
+	//		end
+	//end
+
+endmodule
+