diff --git a/lab5/bench.sv b/lab5/bench.sv new file mode 100644 index 0000000..c95f124 --- /dev/null +++ b/lab5/bench.sv @@ -0,0 +1,121 @@ +`include "src/top.sv" +`include "src/utils.sv" + +module bench(); + + timeunit 10ns; + timeprecision 1ns; + + logic Run = 1, Continue = 1, Clk = 0; + logic [9:0] SW, LED; + `TOGGLE_INTERNAL + logic [15:0] hexval, R0, R1, R2, R3, R4, R5, R6, R7; + + assign R0 = REG[0]; + assign R1 = REG[1]; + assign R2 = REG[2]; + assign R3 = REG[3]; + assign R4 = REG[4]; + assign R5 = REG[5]; + assign R6 = REG[6]; + assign R7 = REG[7]; + + SLC3TopSim subject(.*); + +`define NUM1 10'h3EC +`define NUM2 10'h0EB +`define NUM3 10'h2CA +`define NUM4 10'h1FE +`define TICK #80 +`define RUN `TICK Run = 0; `TICK Run = 1; +`define CONT `TICK Continue = 0; `TICK Continue = 1; +`define RESET `TICK Run = 0; Continue = 0; `TICK Run = 1; Continue = 1; +`define SETSW(val) `TICK SW = val; + + initial begin: CLOCK_INIT + Clk = 0; + end + + always begin: CLOCK_GEN + #1 Clk = ~Clk; + end + + initial begin: TEST_VECT + +`ifdef FETCH_DEMO + + `RESET + `RUN + for (int i = 0; i < 80; i++) begin + `CONT + end + +`else + + // I/O 1 + `RESET + `SETSW(10'h03) + `RUN + `SETSW(`NUM1) + `SETSW(`NUM2) + `SETSW(`NUM3) + `SETSW(`NUM4) + + // I/O 2 + `RESET + `SETSW(10'h06) + `RUN + `SETSW(`NUM1) `CONT + `SETSW(`NUM2) `CONT + `SETSW(`NUM3) `CONT + `SETSW(`NUM4) `CONT + + // Self-mod + `RESET + `SETSW(10'h0B) + `RUN + for (int i = 0; i < 16; i++) begin + `CONT + end + + // XOR + `RESET + `SETSW(10'h14) + `RUN + `SETSW(`NUM1) `CONT + `SETSW(`NUM2) `CONT + `CONT + `SETSW(`NUM3) `CONT + `SETSW(`NUM4) `CONT + `CONT + + // Mult + `RESET + `SETSW(10'h31) + `RUN + `SETSW(`NUM1) `CONT + `SETSW(`NUM2) `CONT + `TICK `CONT + `SETSW(`NUM3) `CONT + `SETSW(`NUM4) `CONT + `TICK `CONT + + // Sort + `RESET + `SETSW(10'h5A) + `RUN + `SETSW(10'h3) `CONT + for (int i = 0; i < 16; i++) begin + `CONT + end + `SETSW(10'h2) `CONT + `SETSW(10'h3) `CONT + for (int i = 0; i < 16; i++) begin + `CONT + end + +`endif + + end + +endmodule diff --git a/lab5/ece385lab5.out.sdc b/lab5/ece385lab5.out.sdc new file mode 100644 index 0000000..e4cc132 --- /dev/null +++ b/lab5/ece385lab5.out.sdc @@ -0,0 +1,7 @@ +set_time_format -unit ns -decimal_places 3 +create_clock -name {Clk} -period 10.000 -waveform { 0.000 10.000 } [get_ports {Clk}] +set_input_delay -add_delay -rise -clock [get_clocks {Clk}] 0.500 [get_ports {Run}] +set_input_delay -add_delay -rise -clock [get_clocks {Clk}] 0.500 [get_ports {Continue}] +set_input_delay -add_delay -rise -clock [get_clocks {Clk}] 0.000 [get_ports {SW*}] +set_output_delay -add_delay -rise -clock [get_clocks {Clk}] 0.000 [get_ports {LED*}] +set_output_delay -add_delay -rise -clock [get_clocks {Clk}] 0.000 [get_ports {HEX*}] diff --git a/lab5/ece385lab5.qpf b/lab5/ece385lab5.qpf new file mode 100644 index 0000000..2439e05 --- /dev/null +++ b/lab5/ece385lab5.qpf @@ -0,0 +1,6 @@ +QUARTUS_VERSION = "18.1" +DATE = "10:00:00 February 18, 2023" + +# Revisions + +PROJECT_REVISION = "ece385lab5" diff --git a/lab5/ece385lab5.qsf b/lab5/ece385lab5.qsf new file mode 100644 index 0000000..b09e89d --- /dev/null +++ b/lab5/ece385lab5.qsf @@ -0,0 +1,103 @@ +set_global_assignment -name FAMILY "MAX 10" +set_global_assignment -name DEVICE 10M50DAF484C7G +set_global_assignment -name TOP_LEVEL_ENTITY SLC3Top +set_global_assignment -name ORIGINAL_QUARTUS_VERSION 18.1.0 +set_global_assignment -name PROJECT_CREATION_TIME_DATE "10:00:00 FEBRUARY 18, 2023" +set_global_assignment -name LAST_QUARTUS_VERSION "18.1.0 Lite Edition" +set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 +set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 256 +set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim-Altera (SystemVerilog)" +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 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 POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" +set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" +set_global_assignment -name SYSTEMVERILOG_FILE src/top.sv +set_global_assignment -name SYSTEMVERILOG_FILE src/topsim.sv +set_global_assignment -name SYSTEMVERILOG_FILE src/topsynth.sv +set_global_assignment -name SYSTEMVERILOG_FILE src/slc3.sv +set_global_assignment -name SYSTEMVERILOG_FILE src/slc3isdu.sv +set_global_assignment -name SYSTEMVERILOG_FILE src/slc3pkg.sv +set_global_assignment -name SYSTEMVERILOG_FILE src/memsim.sv +set_global_assignment -name SYSTEMVERILOG_FILE src/memsynth.sv +set_global_assignment -name SYSTEMVERILOG_FILE src/mem2io.sv +set_global_assignment -name SYSTEMVERILOG_FILE src/utils.sv +set_global_assignment -name QIP_FILE ram/ram.qip +set_global_assignment -name SDC_FILE ece385lab5.out.sdc +set_location_assignment PIN_P11 -to Clk +set_location_assignment PIN_A7 -to Run +set_location_assignment PIN_B8 -to Continue +set_location_assignment PIN_C10 -to SW[0] +set_location_assignment PIN_C11 -to SW[1] +set_location_assignment PIN_D12 -to SW[2] +set_location_assignment PIN_C12 -to SW[3] +set_location_assignment PIN_A12 -to SW[4] +set_location_assignment PIN_B12 -to SW[5] +set_location_assignment PIN_A13 -to SW[6] +set_location_assignment PIN_A14 -to SW[7] +set_location_assignment PIN_B14 -to SW[8] +set_location_assignment PIN_F15 -to SW[9] +set_location_assignment PIN_A8 -to LED[0] +set_location_assignment PIN_A9 -to LED[1] +set_location_assignment PIN_A10 -to LED[2] +set_location_assignment PIN_B10 -to LED[3] +set_location_assignment PIN_D13 -to LED[4] +set_location_assignment PIN_C13 -to LED[5] +set_location_assignment PIN_E14 -to LED[6] +set_location_assignment PIN_D14 -to LED[7] +set_location_assignment PIN_A11 -to LED[8] +set_location_assignment PIN_B11 -to LED[9] +set_location_assignment PIN_C14 -to HEX0[0] +set_location_assignment PIN_E15 -to HEX0[1] +set_location_assignment PIN_C15 -to HEX0[2] +set_location_assignment PIN_C16 -to HEX0[3] +set_location_assignment PIN_E16 -to HEX0[4] +set_location_assignment PIN_D17 -to HEX0[5] +set_location_assignment PIN_C17 -to HEX0[6] +set_location_assignment PIN_C18 -to HEX1[0] +set_location_assignment PIN_D18 -to HEX1[1] +set_location_assignment PIN_E18 -to HEX1[2] +set_location_assignment PIN_B16 -to HEX1[3] +set_location_assignment PIN_A17 -to HEX1[4] +set_location_assignment PIN_A18 -to HEX1[5] +set_location_assignment PIN_B17 -to HEX1[6] +set_location_assignment PIN_B20 -to HEX2[0] +set_location_assignment PIN_A20 -to HEX2[1] +set_location_assignment PIN_B19 -to HEX2[2] +set_location_assignment PIN_A21 -to HEX2[3] +set_location_assignment PIN_B21 -to HEX2[4] +set_location_assignment PIN_C22 -to HEX2[5] +set_location_assignment PIN_B22 -to HEX2[6] +set_location_assignment PIN_F21 -to HEX3[0] +set_location_assignment PIN_E22 -to HEX3[1] +set_location_assignment PIN_E21 -to HEX3[2] +set_location_assignment PIN_C19 -to HEX3[3] +set_location_assignment PIN_C20 -to HEX3[4] +set_location_assignment PIN_D19 -to HEX3[5] +set_location_assignment PIN_E17 -to HEX3[6] +set_location_assignment PIN_F18 -to HEX4[0] +set_location_assignment PIN_E20 -to HEX4[1] +set_location_assignment PIN_E19 -to HEX4[2] +set_location_assignment PIN_J18 -to HEX4[3] +set_location_assignment PIN_H19 -to HEX4[4] +set_location_assignment PIN_F19 -to HEX4[5] +set_location_assignment PIN_F20 -to HEX4[6] +set_location_assignment PIN_J20 -to HEX5[0] +set_location_assignment PIN_K20 -to HEX5[1] +set_location_assignment PIN_L18 -to HEX5[2] +set_location_assignment PIN_N18 -to HEX5[3] +set_location_assignment PIN_M20 -to HEX5[4] +set_location_assignment PIN_N19 -to HEX5[5] +set_location_assignment PIN_N20 -to HEX5[6] +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 bench -section_id eda_simulation +set_global_assignment -name EDA_TEST_BENCH_NAME bench -section_id eda_simulation +set_global_assignment -name EDA_DESIGN_INSTANCE_NAME NA -section_id bench +set_global_assignment -name EDA_TEST_BENCH_RUN_SIM_FOR "500 us" -section_id bench +set_global_assignment -name EDA_TEST_BENCH_MODULE_NAME bench -section_id bench +set_global_assignment -name EDA_TEST_BENCH_FILE bench.sv -section_id bench +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/lab5/filename_map.md b/lab5/filename_map.md new file mode 100644 index 0000000..418e226 --- /dev/null +++ b/lab5/filename_map.md @@ -0,0 +1,12 @@ +| New Filename | Old Filename | +| - | - | +| `top.sv` | | +| `topsim.sv` | `slc3_testtop.sv` | +| `topsynth.sv` | `slc3_sramtop.sv` | +| `slc3.sv` | `slc3.sv` | +| `slc3isdu.sv` | `ISDU.sv` | +| `slc3pkg.sv` | `SLC3_2.sv` | +| `mem2io.sv` | `Mem2IO.sv` | +| `memsim.sv` | `test_memory.sv`
`memory_contents.sv` | +| `memsynth.sv` | `Instantiateram.sv` | +| `utils.sv` | `synchronizers.sv` | diff --git a/lab5/ram/ram.bsf b/lab5/ram/ram.bsf new file mode 100644 index 0000000..2eeacfe --- /dev/null +++ b/lab5/ram/ram.bsf @@ -0,0 +1,129 @@ +/* +WARNING: Do NOT edit the input and output ports in this file in a text +editor if you plan to continue editing the block that represents it in +the Block Editor! File corruption is VERY likely to occur. +*/ +/* +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. +*/ +(header "symbol" (version "1.2")) +(symbol + (rect 0 0 216 128) + (text "ram" (rect 91 0 116 16)(font "Arial" (font_size 10))) + (text "inst" (rect 8 112 25 124)(font "Arial" )) + (port + (pt 0 32) + (input) + (text "data[15..0]" (rect 0 0 60 14)(font "Arial" (font_size 8))) + (text "data[15..0]" (rect 4 14 76 31)(font "Arial" (font_size 8))) + (line (pt 0 32)(pt 88 32)(line_width 3)) + ) + (port + (pt 0 48) + (input) + (text "wren" (rect 0 0 30 14)(font "Arial" (font_size 8))) + (text "wren" (rect 4 30 35 47)(font "Arial" (font_size 8))) + (line (pt 0 48)(pt 88 48)) + ) + (port + (pt 0 64) + (input) + (text "address[9..0]" (rect 0 0 75 14)(font "Arial" (font_size 8))) + (text "address[9..0]" (rect 4 46 93 63)(font "Arial" (font_size 8))) + (line (pt 0 64)(pt 88 64)(line_width 3)) + ) + (port + (pt 0 80) + (input) + (text "rden" (rect 0 0 25 14)(font "Arial" (font_size 8))) + (text "rden" (rect 4 62 33 79)(font "Arial" (font_size 8))) + (line (pt 0 80)(pt 88 80)) + ) + (port + (pt 0 112) + (input) + (text "clock" (rect 0 0 29 14)(font "Arial" (font_size 8))) + (text "clock" (rect 4 94 39 111)(font "Arial" (font_size 8))) + (line (pt 0 112)(pt 144 112)) + ) + (port + (pt 216 32) + (output) + (text "q[15..0]" (rect 0 0 42 14)(font "Arial" (font_size 8))) + (text "q[15..0]" (rect 161 14 211 31)(font "Arial" (font_size 8))) + (line (pt 216 32)(pt 160 32)(line_width 3)) + ) + (drawing + (text "16 bits" (rect 105 32 201 177)(font "Arial" )(vertical)) + (text "1024 words" (rect 120 16 231 207)(font "Arial" )(vertical)) + (text "Block type: M9K" (rect 48 110 196 235)(font "Arial" )) + (line (pt 104 24)(pt 136 24)) + (line (pt 136 24)(pt 136 96)) + (line (pt 136 96)(pt 104 96)) + (line (pt 104 96)(pt 104 24)) + (line (pt 118 58)(pt 123 63)) + (line (pt 118 62)(pt 123 57)) + (line (pt 88 27)(pt 96 27)) + (line (pt 96 27)(pt 96 39)) + (line (pt 96 39)(pt 88 39)) + (line (pt 88 39)(pt 88 27)) + (line (pt 88 34)(pt 90 36)) + (line (pt 90 36)(pt 88 38)) + (line (pt 80 36)(pt 88 36)) + (line (pt 96 32)(pt 104 32)(line_width 3)) + (line (pt 152 27)(pt 160 27)) + (line (pt 160 27)(pt 160 39)) + (line (pt 160 39)(pt 152 39)) + (line (pt 152 39)(pt 152 27)) + (line (pt 152 34)(pt 154 36)) + (line (pt 154 36)(pt 152 38)) + (line (pt 144 36)(pt 152 36)) + (line (pt 136 32)(pt 152 32)(line_width 3)) + (line (pt 88 43)(pt 96 43)) + (line (pt 96 43)(pt 96 55)) + (line (pt 96 55)(pt 88 55)) + (line (pt 88 55)(pt 88 43)) + (line (pt 88 50)(pt 90 52)) + (line (pt 90 52)(pt 88 54)) + (line (pt 80 52)(pt 88 52)) + (line (pt 96 48)(pt 104 48)) + (line (pt 88 59)(pt 96 59)) + (line (pt 96 59)(pt 96 71)) + (line (pt 96 71)(pt 88 71)) + (line (pt 88 71)(pt 88 59)) + (line (pt 88 66)(pt 90 68)) + (line (pt 90 68)(pt 88 70)) + (line (pt 80 68)(pt 88 68)) + (line (pt 96 64)(pt 104 64)(line_width 3)) + (line (pt 88 75)(pt 96 75)) + (line (pt 96 75)(pt 96 87)) + (line (pt 96 87)(pt 88 87)) + (line (pt 88 87)(pt 88 75)) + (line (pt 88 82)(pt 90 84)) + (line (pt 90 84)(pt 88 86)) + (line (pt 80 84)(pt 88 84)) + (line (pt 96 80)(pt 104 80)) + (line (pt 80 112)(pt 80 36)) + (line (pt 144 112)(pt 144 36)) + (line (pt 0 0)(pt 217 0)) + (line (pt 217 0)(pt 217 130)) + (line (pt 0 130)(pt 217 130)) + (line (pt 0 0)(pt 0 130)) + (line (pt 0 0)(pt 0 0)) + (line (pt 0 0)(pt 0 0)) + (line (pt 0 0)(pt 0 0)) + (line (pt 0 0)(pt 0 0)) + ) +) diff --git a/lab5/ram/ram.cmp b/lab5/ram/ram.cmp new file mode 100644 index 0000000..a130bfe --- /dev/null +++ b/lab5/ram/ram.cmp @@ -0,0 +1,26 @@ +--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. + + +component ram + PORT + ( + address : IN STD_LOGIC_VECTOR (9 DOWNTO 0); + clock : IN STD_LOGIC := '1'; + data : IN STD_LOGIC_VECTOR (15 DOWNTO 0); + rden : IN STD_LOGIC := '1'; + wren : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (15 DOWNTO 0) + ); +end component; diff --git a/lab5/ram/ram.inc b/lab5/ram/ram.inc new file mode 100644 index 0000000..c1f8994 --- /dev/null +++ b/lab5/ram/ram.inc @@ -0,0 +1,27 @@ +--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. + + +FUNCTION ram +( + address[9..0], + clock, + data[15..0], + rden, + wren +) + +RETURNS ( + q[15..0] +); diff --git a/lab5/ram/ram.qip b/lab5/ram/ram.qip new file mode 100644 index 0000000..ec68358 --- /dev/null +++ b/lab5/ram/ram.qip @@ -0,0 +1,9 @@ +set_global_assignment -name IP_TOOL_NAME "RAM: 1-PORT" +set_global_assignment -name IP_TOOL_VERSION "18.1" +set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "ram.v"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "ram.bsf"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "ram_inst.v"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "ram_bb.v"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "ram.inc"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "ram.cmp"] diff --git a/lab5/ram/ram.v b/lab5/ram/ram.v new file mode 100644 index 0000000..3c88c65 --- /dev/null +++ b/lab5/ram/ram.v @@ -0,0 +1,179 @@ +// megafunction wizard: %RAM: 1-PORT% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: ram.v +// Megafunction Name(s): +// altsyncram +// +// 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 ram ( + address, + clock, + data, + rden, + wren, + q); + + input [9:0] address; + input clock; + input [15:0] data; + input rden; + input wren; + output [15:0] q; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock; + tri1 rden; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [15:0] sub_wire0; + wire [15:0] q = sub_wire0[15:0]; + + altsyncram altsyncram_component ( + .address_a (address), + .clock0 (clock), + .data_a (data), + .rden_a (rden), + .wren_a (wren), + .q_a (sub_wire0), + .aclr0 (1'b0), + .aclr1 (1'b0), + .address_b (1'b1), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b (1'b1), + .eccstatus (), + .q_b (), + .rden_b (1'b1), + .wren_b (1'b0)); + defparam + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_output_a = "BYPASS", + altsyncram_component.intended_device_family = "MAX 10", + altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 1024, + altsyncram_component.operation_mode = "SINGLE_PORT", + altsyncram_component.outdata_aclr_a = "NONE", + altsyncram_component.outdata_reg_a = "CLOCK0", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.ram_block_type = "M9K", + altsyncram_component.read_during_write_mode_port_a = "DONT_CARE", + altsyncram_component.widthad_a = 10, + altsyncram_component.width_a = 16, + altsyncram_component.width_byteena_a = 1; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: AclrAddr NUMERIC "0" +// Retrieval info: PRIVATE: AclrByte NUMERIC "0" +// Retrieval info: PRIVATE: AclrData NUMERIC "0" +// Retrieval info: PRIVATE: AclrOutput NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "1" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: Clken NUMERIC "0" +// Retrieval info: PRIVATE: DataBusSeparated NUMERIC "1" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "MAX 10" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "" +// Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "1024" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "2" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "2" +// Retrieval info: PRIVATE: RegAddr NUMERIC "1" +// Retrieval info: PRIVATE: RegData NUMERIC "1" +// Retrieval info: PRIVATE: RegOutput NUMERIC "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: SingleClock NUMERIC "1" +// Retrieval info: PRIVATE: UseDQRAM NUMERIC "1" +// Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC "0" +// Retrieval info: PRIVATE: WidthAddr NUMERIC "10" +// Retrieval info: PRIVATE: WidthData NUMERIC "16" +// Retrieval info: PRIVATE: rden NUMERIC "1" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "MAX 10" +// Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "1024" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "SINGLE_PORT" +// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0" +// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" +// Retrieval info: CONSTANT: RAM_BLOCK_TYPE STRING "M9K" +// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "DONT_CARE" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "10" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "16" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: USED_PORT: address 0 0 10 0 INPUT NODEFVAL "address[9..0]" +// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +// Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL "data[15..0]" +// Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL "q[15..0]" +// Retrieval info: USED_PORT: rden 0 0 0 0 INPUT VCC "rden" +// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL "wren" +// Retrieval info: CONNECT: @address_a 0 0 10 0 address 0 0 10 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +// Retrieval info: CONNECT: @data_a 0 0 16 0 data 0 0 16 0 +// Retrieval info: CONNECT: @rden_a 0 0 0 0 rden 0 0 0 0 +// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 16 0 @q_a 0 0 16 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL ram.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL ram.inc TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL ram.cmp TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL ram.bsf TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL ram_inst.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL ram_bb.v TRUE +// Retrieval info: LIB_FILE: altera_mf diff --git a/lab5/ram/ram_bb.v b/lab5/ram/ram_bb.v new file mode 100644 index 0000000..7017972 --- /dev/null +++ b/lab5/ram/ram_bb.v @@ -0,0 +1,129 @@ +// megafunction wizard: %RAM: 1-PORT%VBB% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: ram.v +// Megafunction Name(s): +// altsyncram +// +// 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. + +module ram ( + address, + clock, + data, + rden, + wren, + q); + + input [9:0] address; + input clock; + input [15:0] data; + input rden; + input wren; + output [15:0] q; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock; + tri1 rden; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: AclrAddr NUMERIC "0" +// Retrieval info: PRIVATE: AclrByte NUMERIC "0" +// Retrieval info: PRIVATE: AclrData NUMERIC "0" +// Retrieval info: PRIVATE: AclrOutput NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "1" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: Clken NUMERIC "0" +// Retrieval info: PRIVATE: DataBusSeparated NUMERIC "1" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "MAX 10" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "" +// Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "1024" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "2" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "2" +// Retrieval info: PRIVATE: RegAddr NUMERIC "1" +// Retrieval info: PRIVATE: RegData NUMERIC "1" +// Retrieval info: PRIVATE: RegOutput NUMERIC "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: SingleClock NUMERIC "1" +// Retrieval info: PRIVATE: UseDQRAM NUMERIC "1" +// Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC "0" +// Retrieval info: PRIVATE: WidthAddr NUMERIC "10" +// Retrieval info: PRIVATE: WidthData NUMERIC "16" +// Retrieval info: PRIVATE: rden NUMERIC "1" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "MAX 10" +// Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "1024" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "SINGLE_PORT" +// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0" +// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" +// Retrieval info: CONSTANT: RAM_BLOCK_TYPE STRING "M9K" +// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "DONT_CARE" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "10" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "16" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: USED_PORT: address 0 0 10 0 INPUT NODEFVAL "address[9..0]" +// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +// Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL "data[15..0]" +// Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL "q[15..0]" +// Retrieval info: USED_PORT: rden 0 0 0 0 INPUT VCC "rden" +// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL "wren" +// Retrieval info: CONNECT: @address_a 0 0 10 0 address 0 0 10 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +// Retrieval info: CONNECT: @data_a 0 0 16 0 data 0 0 16 0 +// Retrieval info: CONNECT: @rden_a 0 0 0 0 rden 0 0 0 0 +// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 16 0 @q_a 0 0 16 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL ram.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL ram.inc TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL ram.cmp TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL ram.bsf TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL ram_inst.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL ram_bb.v TRUE +// Retrieval info: LIB_FILE: altera_mf diff --git a/lab5/ram/ram_inst.v b/lab5/ram/ram_inst.v new file mode 100644 index 0000000..3d1c057 --- /dev/null +++ b/lab5/ram/ram_inst.v @@ -0,0 +1,8 @@ +ram ram_inst ( + .address ( address_sig ), + .clock ( clock_sig ), + .data ( data_sig ), + .rden ( rden_sig ), + .wren ( wren_sig ), + .q ( q_sig ) + ); diff --git a/lab5/src/mem2io.sv b/lab5/src/mem2io.sv new file mode 100644 index 0000000..66ae362 --- /dev/null +++ b/lab5/src/mem2io.sv @@ -0,0 +1,32 @@ +module Mem2IO ( + input logic rden, wren, Reset, Clk, + input logic [15:0] addr, data_from_CPU, data_from_SRAM, + input logic [9:0] SW, + output logic [15:0] data_to_CPU, data_to_SRAM, + output logic [3:0] hexvals[3:0]); + + logic [15:0] hex_data; + + always_comb begin + data_to_CPU = 16'd0; + if (~wren && rden) + if (addr[15:0] == 16'hFFFF) + data_to_CPU = {6'b000000, SW}; + else + data_to_CPU = data_from_SRAM; + end + + always_ff @ (posedge Clk) begin + if (Reset) + hex_data <= 16'd0; + else if (wren && (addr[15:0] == 16'hFFFF)) + hex_data <= data_from_CPU; + end + + assign hexvals[0] = hex_data[3:0]; + assign hexvals[1] = hex_data[7:4]; + assign hexvals[2] = hex_data[11:8]; + assign hexvals[3] = hex_data[15:12]; + assign data_to_SRAM = data_from_CPU; + +endmodule diff --git a/lab5/src/memsim.sv b/lab5/src/memsim.sv new file mode 100644 index 0000000..a4c0526 --- /dev/null +++ b/lab5/src/memsim.sv @@ -0,0 +1,264 @@ +`include "slc3pkg.sv" +import SLC3_2::*; + + +module MemSim ( + input logic rden, wren, Reset, Clk, + input logic [9:0] addr, + input logic [15:0] data, + output logic [15:0] readout); + + parameter memsize = 256; + parameter external_init = 0; + + logic [15:0] mem_array[0:memsize-1]; + logic [15:0] mem_out; + + MemSimParser #(.memsize(memsize)) parser(); + +// synthesis translate_off + + initial begin + parser.parse(mem_array); + if (~external_init) begin + integer fptr = $fopen("memsimparser.mif", "w"); + for (integer i = 0; i < memsize; i++) begin + $fwrite(fptr, "@%0h %0h\n", i, mem_array[i]); + end + $fclose(fptr); + end + $readmemh("memsimparser.mif", mem_array, 0, memsize-1); + end + + always @ (posedge Clk or posedge Reset) begin + if (Reset) begin + $readmemh("memsimparser.mif", mem_array, 0, memsize-1); + mem_out <= 16'bX; + end else if (rden && ~wren) begin + mem_out <= mem_array[addr[7:0]]; + end else if (~rden && wren) begin + mem_array[addr[7:0]] <= data; + mem_out <= 16'bX; + end else begin + mem_out <= 16'bX; + end + end + + assign readout = mem_out; + +// synthesis translate_on + +endmodule + + +module MemSimParser; + + parameter memsize = 256; + + task parse(output logic[15:0] mem_array[0:memsize-1]); + + mem_array[ 0 ] = opCLR(R0) ; + mem_array[ 1 ] = opLDR(R1, R0, inSW) ; + mem_array[ 2 ] = opJMP(R1) ; + + /* Basic I/O test 1 */ + mem_array[ 3 ] = opLDR(R1, R0, inSW) ; + mem_array[ 4 ] = opSTR(R1, R0, outHEX); + mem_array[ 5 ] = opBR(nzp, -3) ; + + /* Basic I/O test 2 */ + mem_array[ 6 ] = opPSE(12'h801) ; + mem_array[ 7 ] = opLDR(R1, R0, inSW) ; + mem_array[ 8 ] = opSTR(R1, R0, outHEX); + mem_array[ 9 ] = opPSE(12'hC02) ; + mem_array[ 10 ] = opBR(nzp, -4) ; + + /* Basic I/O test 3 (Self-modifying code) */ + mem_array[ 11 ] = opPSE(12'h801) ; + mem_array[ 12 ] = opJSR(0) ; + mem_array[ 13 ] = opLDR(R2,R7,3) ; + mem_array[ 14 ] = opLDR(R1, R0, inSW) ; + mem_array[ 15 ] = opSTR(R1, R0, outHEX); + mem_array[ 16 ] = opPSE(12'hC02) ; + mem_array[ 17 ] = opINC(R2) ; + mem_array[ 18 ] = opSTR(R2,R7,3) ; + mem_array[ 19 ] = opBR(nzp, -6) ; + + /* XOR test */ + mem_array[ 20 ] = opCLR(R0) ; + mem_array[ 21 ] = opPSE(12'h801) ; + mem_array[ 22 ] = opLDR(R1, R0, inSW) ; + mem_array[ 23 ] = opPSE(12'h802) ; + mem_array[ 24 ] = opLDR(R2, R0, inSW) ; + mem_array[ 25 ] = opNOT(R3, R1) ; + mem_array[ 26 ] = opAND(R3, R3, R2) ; + mem_array[ 27 ] = opNOT(R3, R3) ; + mem_array[ 28 ] = opNOT(R4, R2) ; + mem_array[ 29 ] = opAND(R4, R4, R1) ; + mem_array[ 30 ] = opNOT(R4, R4) ; + mem_array[ 31 ] = opAND(R3, R3, R4) ; + mem_array[ 32 ] = opNOT(R3, R3) ; + mem_array[ 33 ] = opSTR(R3, R0, outHEX); + mem_array[ 34 ] = opPSE(12'h405) ; + mem_array[ 35 ] = opBR(nzp, -15) ; + mem_array[ 36 ] = NO_OP ; + mem_array[ 37 ] = NO_OP ; + mem_array[ 38 ] = NO_OP ; + mem_array[ 39 ] = NO_OP ; + mem_array[ 40 ] = NO_OP ; + mem_array[ 41 ] = NO_OP ; + + /* Run once test (also for JMP) */ + mem_array[ 42 ] = opCLR(R0) ; + mem_array[ 43 ] = opCLR(R1) ; + mem_array[ 44 ] = opJSR(0) ; + mem_array[ 45 ] = opSTR(R1, R0, outHEX); + mem_array[ 46 ] = opPSE(12'h401) ; + mem_array[ 47 ] = opINC(R1) ; + mem_array[ 48 ] = opRET() ; + + /* Multiplier Program */ + mem_array[ 49 ] = opCLR(R0) ; + mem_array[ 50 ] = opJSR(0) ; + mem_array[ 51 ] = opLDR(R3, R7, 22) ; + mem_array[ 52 ] = opCLR(R4) ; + mem_array[ 53 ] = opCLR(R5) ; + mem_array[ 54 ] = opPSE(12'h801) ; + mem_array[ 55 ] = opLDR(R1, R0, inSW) ; + mem_array[ 56 ] = opPSE(12'h802) ; + mem_array[ 57 ] = opLDR(R2, R0, inSW) ; + mem_array[ 58 ] = opADD(R5, R5, R5) ; + mem_array[ 59 ] = opAND(R7, R3, R1) ; + mem_array[ 60 ] = opBR(z, 1) ; + mem_array[ 61 ] = opADD(R5, R5, R2) ; + mem_array[ 62 ] = opADDi(R4, R4, 0) ; + mem_array[ 63 ] = opBR(p,2) ; + mem_array[ 64 ] = opNOT(R5, R5) ; + mem_array[ 65 ] = opINC(R5) ; + mem_array[ 66 ] = opINC(R4) ; + mem_array[ 67 ] = opADD(R1, R1, R1) ; + mem_array[ 68 ] = opADDi(R7, R4, -8) ; + mem_array[ 69 ] = opBR(n, -12) ; + mem_array[ 70 ] = opSTR(R5, R0, outHEX); + mem_array[ 71 ] = opPSE(12'h403) ; + mem_array[ 72 ] = opBR(nzp, -21) ; + mem_array[ 73 ] = 16'h0080 ; + + /* Data for Bubble Sort */ + mem_array[ 74 ] = 16'h00EF ; + mem_array[ 75 ] = 16'h001B ; + mem_array[ 76 ] = 16'h0001 ; + mem_array[ 77 ] = 16'h008C ; + mem_array[ 78 ] = 16'h00DB ; + mem_array[ 79 ] = 16'h00FA ; + mem_array[ 80 ] = 16'h0047 ; + mem_array[ 81 ] = 16'h0046 ; + mem_array[ 82 ] = 16'h001F ; + mem_array[ 83 ] = 16'h000d ; + mem_array[ 84 ] = 16'h00B8 ; + mem_array[ 85 ] = 16'h0003 ; + mem_array[ 86 ] = 16'h006B ; + mem_array[ 87 ] = 16'h004E ; + mem_array[ 88 ] = 16'h00F8 ; + mem_array[ 89 ] = 16'h0007 ; + mem_array[ 90 ] = opCLR(R0) ; + mem_array[ 91 ] = opJSR(0) ; + mem_array[ 92 ] = opADDi(R6, R7, -16) ; + mem_array[ 93 ] = opADDi(R6, R6, -2) ; + mem_array[ 94 ] = opPSE(12'hBFF) ; + mem_array[ 95 ] = opLDR(R1, R0, inSW) ; + mem_array[ 96 ] = opBR(z, -3) ; + mem_array[ 97 ] = opDEC(R1) ; + mem_array[ 98 ] = opBR(np, 2) ; + mem_array[ 99 ] = opJSR(9) ; + mem_array[ 100 ] = opBR(nzp, -7) ; + mem_array[ 101 ] = opDEC(R1) ; + mem_array[ 102 ] = opBR(np, 2) ; + mem_array[ 103 ] = opJSR(15) ; + mem_array[ 104 ] = opBR(nzp, -11) ; + mem_array[ 105 ] = opDEC(R1) ; + mem_array[ 106 ] = opBR(np, -13) ; + mem_array[ 107 ] = opJSR(29) ; + mem_array[ 108 ] = opBR(nzp, -15) ; + mem_array[ 109 ] = opCLR(R1) ; + mem_array[ 110 ] = opSTR(R1, R0, outHEX); + mem_array[ 111 ] = opPSE(12'hC01) ; + mem_array[ 112 ] = opLDR(R2, R0, inSW) ; + mem_array[ 113 ] = opADD(R5, R6, R1) ; + mem_array[ 114 ] = opSTR(R2, R5, 0) ; + mem_array[ 115 ] = opINC(R1) ; + mem_array[ 116 ] = opADDi(R3, R1, -16) ; + mem_array[ 117 ] = opBR(n, -8) ; + mem_array[ 118 ] = opRET() ; + mem_array[ 119 ] = opADDi(R1, R0, -16) ; + mem_array[ 120 ] = opADDi(R2, R0, 1) ; + mem_array[ 121 ] = opADD(R3, R6, R2) ; + mem_array[ 122 ] = opLDR(R4, R3, -1) ; + mem_array[ 123 ] = opLDR(R5, R3, 0) ; + mem_array[ 124 ] = opNOT(R5, R5) ; + mem_array[ 125 ] = opADDi(R5, R5, 1) ; + mem_array[ 126 ] = opADD(R5, R4, R5) ; + mem_array[ 127 ] = opBR(nz, 3) ; + mem_array[ 128 ] = opLDR(R5, R3, 0) ; + mem_array[ 129 ] = opSTR(R5, R3, -1) ; + mem_array[ 130 ] = opSTR(R4, R3, 0) ; + mem_array[ 131 ] = opINC(R2) ; + mem_array[ 132 ] = opADD(R3, R1, R2) ; + mem_array[ 133 ] = opBR(n, -13) ; + mem_array[ 134 ] = opINC(R1) ; + mem_array[ 135 ] = opBR(n, -16) ; + mem_array[ 136 ] = opRET() ; + mem_array[ 137 ] = opCLR(R1) ; + mem_array[ 138 ] = opADD(R4, R7, R0) ; + mem_array[ 139 ] = opJSR(0) ; + mem_array[ 140 ] = opADD(R5, R7, R0) ; + mem_array[ 141 ] = opADD(R7, R4, R0) ; + mem_array[ 142 ] = opLDR(R3, R5, 15) ; + mem_array[ 143 ] = opADDi(R2, R0, 8) ; + mem_array[ 144 ] = opADD(R2, R2, R2) ; + mem_array[ 145 ] = opADD(R4, R6, R1) ; + mem_array[ 146 ] = opLDR(R4, R4, 0) ; + mem_array[ 147 ] = opSTR(R4, R0, outHEX); + mem_array[ 148 ] = opPSE(12'h402) ; + mem_array[ 149 ] = opADD(R3, R3, R2) ; + mem_array[ 150 ] = opSTR(R3, R5, 8) ; + mem_array[ 151 ] = opINC(R1) ; + mem_array[ 152 ] = opADDi(R4, R1, -16) ; + mem_array[ 153 ] = opBR(n, -9) ; + mem_array[ 154 ] = opRET() ; + mem_array[ 155 ] = opPSE(12'h802) ; + + /* Auto counting test */ + mem_array[ 156 ] = opCLR(R0) ; + mem_array[ 157 ] = opCLR(R1) ; + mem_array[ 158 ] = opCLR(R2) ; + mem_array[ 159 ] = opCLR(R3) ; + mem_array[ 160 ] = opJSR(0) ; + // INIT: (PC = 161) + mem_array[ 161 ] = opLDR(R1, R7, 12) ; + mem_array[ 162 ] = opLDR(R2, R7, 13) ; + // 1ST LOOP: (PC = 163) + mem_array[ 163 ] = opDEC(R1) ; + mem_array[ 164 ] = opBR(z, 1) ; + mem_array[ 165 ] = opBR(nzp, -3) ; + // 2ND LOOP: (PC = 166) + mem_array[ 166 ] = opDEC(R2) ; + mem_array[ 167 ] = opBR(z, 2) ; + mem_array[ 168 ] = opLDR(R1, R7, 12) ; + mem_array[ 169 ] = opBR(nzp, -7) ; + // DISPLAY: (PC = 170) + mem_array[ 170 ] = opSTR(R3, R0, outHEX); + mem_array[ 171 ] = opINC(R3) ; + mem_array[ 172 ] = opBR(nzp, -12) ; + // CONSTANTS: (PC = 173) + mem_array[ 173 ] = 16'h3 ; + mem_array[ 174 ] = 16'd3 ; + + /* Assign the rest of the memory to 0 */ + for (integer i = 175; i <= memsize - 1; i++) begin + mem_array[i] = 16'h0; + end + + endtask + +endmodule diff --git a/lab5/src/memsynth.sv b/lab5/src/memsynth.sv new file mode 100644 index 0000000..95557c7 --- /dev/null +++ b/lab5/src/memsynth.sv @@ -0,0 +1,256 @@ +`include "slc3pkg.sv" +import SLC3_2::*; + + +module MemSynth ( + input logic Reset, Clk, + output logic wren, + output logic [15:0] addr_init, data_init); + + logic [15:0] addr; + logic accum; + + enum logic [1:0] {idle, mem_write, done} state, next_state; + + always_ff @ (posedge Clk or posedge Reset) begin + if (Reset) begin + state <= mem_write; + addr <= 16'h0; + end else begin + state <= next_state; + if (accum) + addr <= addr + 16'h1; + else + addr <= addr; + end + end + + always_comb begin + + next_state = state; + wren = 1'b0; + accum = 1'b0; + + unique case (state) + idle: ; + mem_write: begin + if (addr == 16'hFF) + next_state = done; + else + next_state = mem_write; + wren = 1'b1; + accum = 1'b1; + end + done: next_state = idle; + endcase + + case (addr) + + 16'd0: data_init = opCLR(R0) ; // Clear the register so it can be used as a base + 16'd1: data_init = opLDR(R1, R0, inSW) ; // Load switches + 16'd2: data_init = opJMP(R1) ; // Jump to the start of a program + + /* Basic I/O test 1 */ + 16'd3: data_init = opLDR(R1, R0, inSW) ; // Load switches + 16'd4: data_init = opSTR(R1, R0, outHEX); // Output + 16'd5: data_init = opBR(nzp, -3) ; // Repeat + + /* Basic I/O test 2 */ + 16'd6: data_init = opPSE(12'h801) ; // Checkpoint 1 - prepare to input + 16'd7: data_init = opLDR(R1, R0, inSW) ; // Load switches + 16'd8: data_init = opSTR(R1, R0, outHEX); // Output + 16'd9: data_init = opPSE(12'hC02) ; // Checkpoint 2 - read output, prepare to input + 16'd10: data_init = opBR(nzp, -4) ; // Repeat + + /* Basic I/O test 3 (Self-modifying code) */ + 16'd11: data_init = opPSE(12'h801) ; // Checkpoint 1 - prepare to input + 16'd12: data_init = opJSR(0) ; // Get PC addr + 16'd13: data_init = opLDR(R2, R7, 3) ; // Load pause instruction as data + 16'd14: data_init = opLDR(R1, R0, inSW) ; // Load switches + 16'd15: data_init = opSTR(R1, R0, outHEX); // Output + 16'd16: data_init = opPSE(12'hC02) ; // Checkpoint 2 - read output, prepare to input + 16'd17: data_init = opINC(R2) ; // Increment checkpoint number + 16'd18: data_init = opSTR(R2, R7, 3) ; // Store new checkpoint instruction (self-modifying code) + 16'd19: data_init = opBR(nzp, -6) ; // Repeat + + /* XOR test */ + 16'd20: data_init = opCLR(R0) ; + 16'd21: data_init = opPSE(12'h801) ; // Checkpoint 1 - prepare to input (upper) + 16'd22: data_init = opLDR(R1, R0, inSW) ; // Load switches + 16'd23: data_init = opPSE(12'h802) ; // Checkpoint 2 - prepare to input (lower) + 16'd24: data_init = opLDR(R2, R0, inSW) ; // Load switches again + 16'd25: data_init = opNOT(R3, R1) ; // R3: A' + 16'd26: data_init = opAND(R3, R3, R2) ; // R3: A'B + 16'd27: data_init = opNOT(R3, R3) ; // R3: (A'B)' + 16'd28: data_init = opNOT(R4, R2) ; // R4: B' + 16'd29: data_init = opAND(R4, R4, R1) ; // R4: B'A + 16'd30: data_init = opNOT(R4, R4) ; // R4: (B'A)' + 16'd31: data_init = opAND(R3, R3, R4) ; // R3: (A'B)'(B'A)' + 16'd32: data_init = opNOT(R3, R3) ; // R3: ((A'B)'(B'A)')' XOR using only and-not + 16'd33: data_init = opSTR(R3, R0, outHEX); // Output + 16'd34: data_init = opPSE(12'h405) ; // Checkpoint 5 - read output + 16'd35: data_init = opBR(nzp, -15) ; // Repeat + 16'd36: data_init = NO_OP ; + 16'd37: data_init = NO_OP ; + 16'd38: data_init = NO_OP ; + 16'd39: data_init = NO_OP ; + 16'd40: data_init = NO_OP ; + 16'd41: data_init = NO_OP ; + + /* Run once test (also for JMP) */ + 16'd42: data_init = opCLR(R0) ; + 16'd43: data_init = opCLR(R1) ; // clear R1 + 16'd44: data_init = opJSR(0) ; // get jumpback addr + 16'd45: data_init = opSTR(R1, R0, outHEX); // output R1; LOOP DEST + 16'd46: data_init = opPSE(12'h401) ; // Checkpoint 1 - read output + 16'd47: data_init = opINC(R1) ; // increment R1 + 16'd48: data_init = opRET() ; // repeat + + /* Multiplier Program */ + 16'd49: data_init = opCLR(R0) ; + 16'd50: data_init = opJSR(0) ; // R7 <- PC (for loading bit test mask) + 16'd51: data_init = opLDR(R3, R7, 22) ; // load mask; + 16'd52: data_init = opCLR(R4) ; // clear R4 (iteration tracker), ; START + 16'd53: data_init = opCLR(R5) ; // R5 (running total) + 16'd54: data_init = opPSE(12'h801) ; // Checkpoint 1 - prepare to input + 16'd55: data_init = opLDR(R1, R0, inSW) ; // Input operand 1 + 16'd56: data_init = opPSE(12'h802) ; // Checkpoint 2 - prepare to input + 16'd57: data_init = opLDR(R2, R0, inSW) ; // Input operand 2 + 16'd58: data_init = opADD(R5, R5, R5) ; // shift running total; LOOP DEST + 16'd59: data_init = opAND(R7, R3, R1) ; // apply mask + 16'd60: data_init = opBR(z, 1) ; // test bit and jump over... + 16'd61: data_init = opADD(R5, R5, R2) ; // ... the addition + 16'd62: data_init = opADDi(R4, R4, 0) ; // test iteration = = 0 (first iteration) + 16'd63: data_init = opBR(p, 2) ; // if not first iteration, jump over negation + 16'd64: data_init = opNOT(R5, R5) ; // 2's compliment negate R5 + 16'd65: data_init = opINC(R5) ; // (part of above) + 16'd66: data_init = opINC(R4) ; // increment iteration + 16'd67: data_init = opADD(R1, R1, R1) ; // shift operand 1 for mask comparisons + 16'd68: data_init = opADDi(R7, R4, -8) ; // test for last iteration + 16'd69: data_init = opBR(n, -12) ; // branch back to LOOP DEST if iteration < 7 + 16'd70: data_init = opSTR(R5, R0, outHEX); // Output result + 16'd71: data_init = opPSE(12'h403) ; // Checkpoint 3 - read output + 16'd72: data_init = opBR(nzp, -21) ; // loop back to start + 16'd73: data_init = 16'h0080 ; // bit test mask + + /* Data for Bubble Sort */ + 16'd74: data_init = 16'h00EF ; + 16'd75: data_init = 16'h001B ; + 16'd76: data_init = 16'h0001 ; + 16'd77: data_init = 16'h008C ; + 16'd78: data_init = 16'h00DB ; + 16'd79: data_init = 16'h00FA ; + 16'd80: data_init = 16'h0047 ; + 16'd81: data_init = 16'h0046 ; + 16'd82: data_init = 16'h001F ; + 16'd83: data_init = 16'h000D ; + 16'd84: data_init = 16'h00B8 ; + 16'd85: data_init = 16'h0003 ; + 16'd86: data_init = 16'h006B ; + 16'd87: data_init = 16'h004E ; + 16'd88: data_init = 16'h00F8 ; + 16'd89: data_init = 16'h0007 ; + + /* Bubblesort Program */ + 16'd90: data_init = opCLR(R0) ; + 16'd91: data_init = opJSR(0) ; + 16'd92: data_init = opADDi(R6, R7, -16) ; // Store data location in R6 + 16'd93: data_init = opADDi(R6, R6, -2) ; // (data location is 18 above the addr from JSR) + 16'd94: data_init = opPSE(12'hBFF) ; // Checkpoint -1 - select function; LOOP DEST + 16'd95: data_init = opLDR(R1, R0, inSW) ; + 16'd96: data_init = opBR(z, -3) ; // If 0, retry + 16'd97: data_init = opDEC(R1) ; + 16'd98: data_init = opBR(np, 2) ; // if selection wasn't 1, jump over + 16'd99: data_init = opJSR(9) ; // ...call to entry function + 16'd100: data_init = opBR(nzp, -7) ; + 16'd101: data_init = opDEC(R1) ; + 16'd102: data_init = opBR(np, 2) ; // if selection wasn't 2, jump over + 16'd103: data_init = opJSR(15) ; // ...call to sort function + 16'd104: data_init = opBR(nzp, -11) ; + 16'd105: data_init = opDEC(R1) ; + 16'd106: data_init = opBR(np, -13) ; // if selection wasn't 3, retry + 16'd107: data_init = opJSR(29) ; // call to display function + 16'd108: data_init = opBR(nzp, -15) ; // repeat menu + 16'd109: data_init = opCLR(R1) ; // ENTRY FUNCTION + 16'd110: data_init = opSTR(R1, R0, outHEX); // R5 is temporary index into data; R1 is counter; LOOP DEST + 16'd111: data_init = opPSE(12'hC01) ; // Checkpoint 1 - read data (index) and write new value + 16'd112: data_init = opLDR(R2, R0, inSW) ; + 16'd113: data_init = opADD(R5, R6, R1) ; // generate pointer to data + 16'd114: data_init = opSTR(R2, R5, 0) ; // store data + 16'd115: data_init = opINC(R1) ; // increment counter + 16'd116: data_init = opADDi(R3, R1, -16) ; // test for counter = = 16 + 16'd117: data_init = opBR(n, -8) ; // less than 16, repeat + 16'd118: data_init = opRET() ; // ENTRY FUNCTION RETURN + 16'd119: data_init = opADDi(R1, R0, -16) ; // i = -16; SORT FUNCTION + 16'd120: data_init = opADDi(R2, R0, 1) ; // j = 1; OUTER LOOP DEST + 16'd121: data_init = opADD(R3, R6, R2) ; // generate pointer to data; INNER LOOP DEST + 16'd122: data_init = opLDR(R4, R3, -1) ; // R4 = data[j-1] + 16'd123: data_init = opLDR(R5, R3, 0) ; // R5 = data[j] + 16'd124: data_init = opNOT(R5, R5) ; + 16'd125: data_init = opADDi(R5, R5, 1) ; // R5 = -data[j] + 16'd126: data_init = opADD(R5, R4, R5) ; // R5 = data[j-1]-data[j] + 16'd127: data_init = opBR(nz, 3) ; // if data[j-1] > data[j] + 16'd128: data_init = opLDR(R5, R3, 0) ; // { R5 = data[j] + 16'd129: data_init = opSTR(R5, R3, -1) ; // data[j-1] = data[j] + 16'd130: data_init = opSTR(R4, R3, 0) ; // data[j] = R4 } // old data[j-1] + 16'd131: data_init = opINC(R2) ; + 16'd132: data_init = opADD(R3, R1, R2) ; // Compare i and j + 16'd133: data_init = opBR(n, -13) ; // INNER LOOP BACK + 16'd134: data_init = opINC(R1) ; + 16'd135: data_init = opBR(n, -16) ; // OUTER LOOP BACK + 16'd136: data_init = opRET() ; // SORT FUNCTION RETURN + 16'd137: data_init = opCLR(R1) ; // DISPLAY FUNCTION + 16'd138: data_init = opADD(R4, R7, R0) ; // JSR shuffle to get PC value in R5 + 16'd139: data_init = opJSR(0) ; + 16'd140: data_init = opADD(R5, R7, R0) ; + 16'd141: data_init = opADD(R7, R4, R0) ; // shuffle done + 16'd142: data_init = opLDR(R3, R5, 15) ; // R3 = opPSE(12'b802) + 16'd143: data_init = opADDi(R2, R0, 8) ; + 16'd144: data_init = opADD(R2, R2, R2) ; // R2 = 16 + 16'd145: data_init = opADD(R4, R6, R1) ; // generate pointer to data; LOOP DEST + 16'd146: data_init = opLDR(R4, R4, 0) ; // load data + 16'd147: data_init = opSTR(R4, R0, outHEX); // display data + 16'd148: data_init = opPSE(12'h402) ; // Checkpoint 2 - read data (self-modified instruction) + 16'd149: data_init = opADD(R3, R3, R2) ; // modify register with code + 16'd150: data_init = opSTR(R3, R5, 8) ; // store modified code + 16'd151: data_init = opINC(R1) ; // increment counter + 16'd152: data_init = opADDi(R4, R1, -16) ; // test for counter = = 16 + 16'd153: data_init = opBR(n, -9) ; // less than 16, repeat + 16'd154: data_init = opRET() ; // DISPLAY FUNCTION RETURN + 16'd155: data_init = opPSE(12'h802) ; // instruction as data + + /* Auto counter program */ + 16'd156: data_init = opCLR(R0) ; // R0 = 0 + 16'd157: data_init = opCLR(R1) ; // R1 = 0 (R1 will be used as loop counter 1) + 16'd158: data_init = opCLR(R2) ; // R2 = 0 (R2 will be used as loop counter 2) + 16'd159: data_init = opCLR(R3) ; // R3 = 0 (R3 will be displayed to hex displays) + 16'd160: data_init = opJSR(0) ; // R7 <- PC = 161 (161 because PC <- PC+1 after fetch) + // INIT: (PC = 161) + 16'd161: data_init = opLDR(R1, R7, 12) ; // R1 <- xFFFF + 16'd162: data_init = opLDR(R2, R7, 13) ; // R2 <- d5 + // 1ST LOOP: (PC = 163) + 16'd163: data_init = opDEC(R1) ; // Decrement first loop counter + 16'd164: data_init = opBR(z, 1) ; // (Go to 2ND LOOP) - R1 = 0, go to second loop + 16'd165: data_init = opBR(nzp, -3) ; // (Go to 1ST LOOP) - R1 != 0, repeat first loop + // 2ND LOOP: (PC = 166) + 16'd166: data_init = opDEC(R2) ; // Decrement second loop counter + 16'd167: data_init = opBR(z, 2) ; // (Go to DISPLAY) - R2 = 0, show new number on hex displays + 16'd168: data_init = opLDR(R1, R7, 12) ; // R1 <- xFFFF (reset loop 1 counter) + 16'd169: data_init = opBR(nzp, -7) ; // (Go to 1ST LOOP) - R2 != 0, repeat first loop + // DISPLAY: (PC = 170) + 16'd170: data_init = opSTR(R3, R0, outHEX); // Display counter to hex display + 16'd171: data_init = opINC(R3) ; + 16'd172: data_init = opBR(nzp, -12) ; // (Go to INIT) - Repeat double for loop counting + // CONSTANTS: (PC = 173) + 16'd173: data_init = 16'hFFFF ; // Constant for loading into R1 for counting/delay purposes xFFFF + 16'd174: data_init = 16'd5 ; // Constant for loading into R2 for counting/delay purposes d750 + + /* initialize with zero */ + default: data_init = 16'h0000 ; + endcase + + end + + assign addr_init = addr; + +endmodule diff --git a/lab5/src/slc3.sv b/lab5/src/slc3.sv new file mode 100644 index 0000000..0c3e41c --- /dev/null +++ b/lab5/src/slc3.sv @@ -0,0 +1,107 @@ +`include "top.sv" +`include "utils.sv" +`define SEXT(x, digit) {{(16-digit){x[digit-1]}}, x[digit-1:0]} + + +module SLC3 (`TOP_INTERFACE, + input logic Reset, + input logic [15:0] data_from_SRAM, + output logic rden, wren, + output logic [15:0] addr, data_to_SRAM); + + logic BEN, MIO_EN; + logic [3:0] hexvals[3:0]; + logic [15:0] data_to_CPU; +`ifdef SIMULATION + `ifndef INSPECT_CTRL + `INTERNAL_CTRL + `endif + assign hexval = {hexvals[3], hexvals[2], hexvals[1], hexvals[0]}; + logic [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5; +`else + `INTERNAL_REG + `INTERNAL_CTRL +`endif + + assign addr = MAR; + assign MIO_EN = rden; + + Datapath datapath (.*); + ISDU state_controller (.*, + .Opcode(IR[15:12]), .IR_5(IR[5]), .IR_11(IR[11])); + Mem2IO memory_subsystem (.*, .data_from_CPU(MDR)); + +`ifdef FETCH_DEMO + HexDriver hdarr_h[3:0] ({IR[15:12], IR[11:8], IR[7:4], IR[3:0]}, + {HEX5, HEX4, HEX3, HEX2}); +`else + HexDriver hdarr_h[3:0] (hexvals, {HEX5, HEX4, HEX3, HEX2}); +`endif + HexDriver hdarr_l[1:0] ({SW[7:4], SW[3:0]}, {HEX1, HEX0}); + +endmodule + + +module Datapath ( + input logic Reset, Clk, MIO_EN, + input logic [15:0] data_to_CPU, + `INPUT_CTRL +`ifdef SIMULATION + `ifdef INSPECT_NET + `OUTPUT_NET + `endif +`endif + `OUTPUT_REG + output logic BEN, + output logic [9:0] LED); + + /* Notes on the naming rules + * For MUXes: + * - "MUX4 #(16) ", etc. are modules + * - "PCMUX", etc. (ALLCAPS) are ctrl signals + * - "pcmux", etc. (lowercase) are instances + * - "pcmux_out", etc. (*_out) are wires + * For registers: + * - "PC", etc. (ALLCAPS) are wires + * - "pc", etc. (lowercase) are instances */ + +`ifdef SIMULATION + `ifndef INSPECT_NET + `INTERNAL_NET + `endif +`else + `INTERNAL_NET +`endif + + assign cc_in_n = bus_out[15]; + assign cc_in_z = bus_out === 16'b0; + assign cc_in_p = bus_out[15] === 0 & bus_out !== 16'b0; + assign ben_in = (CC_N & IR[11]) | (CC_Z & IR[10]) | (CC_P & IR[9]); + assign adder_out = addr1mux_out + addr2mux_out; + + Bus bus (.out(bus_out), .in1(PC), .in2(marmux_out), .in3(MDR), .in4(alu_out), + .gates({GatePC, GateMARMUX, GateMDR, GateALU})); + RegFile regfile (.*, .regs(REG), .out1(sr1_out), .out2(sr2_out), .in(bus_out), + .DR(drmux_out), .SR1(sr1mux_out), .SR2(IR[2:0])); + ALU alu (.*, .S(alu_out), .A(sr1_out), .B(sr2mux_out)); + + Reg #(16) ir (Reset, Clk, LD_IR, bus_out, IR); + Reg #(16) pc (Reset, Clk, LD_PC, pcmux_out, PC); + Reg #(16) mar (Reset, Clk, LD_MAR, bus_out, MAR); + Reg #(16) mdr (Reset, Clk, LD_MDR, mdrmux_out, MDR); + Reg ben (Reset, Clk, LD_BEN, ben_in, BEN); + Reg led[9:0] (Reset, Clk, LD_LED, bus_out[9:0], LED); + Reg cc[2:0] (Reset, Clk, LD_CC, {cc_in_n, cc_in_z, cc_in_p}, {CC_N, CC_Z, CC_P}); + + MUX4 #(16) pcmux (.S(PCMUX), .out(pcmux_out), .in0(PC + 16'b1), .in1(bus_out), + .in2(adder_out), .in3(16'b0)); + MUX2 #(16) marmux (.S(MARMUX), .out(marmux_out), .in0(adder_out), .in1({4'b0, IR[11:0]})); + MUX2 #(16) mdrmux (.S(MIO_EN), .out(mdrmux_out), .in0(bus_out), .in1(data_to_CPU)); + MUX2 #(3) drmux (.S(DRMUX), .out(drmux_out), .in0(IR[11:9]), .in1(3'b111)); + MUX2 #(3) sr1mux (.S(SR1MUX), .out(sr1mux_out), .in0(IR[11:9]), .in1(IR[8:6])); + MUX2 #(16) sr2mux (.S(SR2MUX), .out(sr2mux_out), .in0(sr2_out), .in1(`SEXT(IR, 5))); + MUX2 #(16) addr1mux (.S(ADDR1MUX), .out(addr1mux_out), .in0(PC), .in1(sr1_out)); + MUX4 #(16) addr2mux (.S(ADDR2MUX), .out(addr2mux_out), .in0(16'b0), .in1(`SEXT(IR, 6)), + .in2(`SEXT(IR, 9)), .in3(`SEXT(IR, 11))); + +endmodule diff --git a/lab5/src/slc3isdu.sv b/lab5/src/slc3isdu.sv new file mode 100644 index 0000000..c17838f --- /dev/null +++ b/lab5/src/slc3isdu.sv @@ -0,0 +1,134 @@ +`include "top.sv" + + +module ISDU ( + input logic Run, Continue, Reset, Clk, + input logic IR_5, IR_11, BEN, + input logic [3:0] Opcode, + `OUTPUT_CTRL + output logic rden, wren); + + enum logic [5:0] { + FCH1 = 6'd18, FCH2w = 6'd37, FCH2x = 6'd39, FCH2 = 6'd33, FCH3 = 6'd35, + LDR1 = 6'd6 , LDR2w = 6'd29, LDR2x = 6'd31, LDR2 = 6'd25, LDR3 = 6'd27, + STR1 = 6'd7 , STR2 = 6'd23, STR3 = 6'd16, + ADD = 6'd1 , AND = 6'd5 , NOT = 6'd9 , + JSR1 = 6'd4 , JSR2 = 6'd21, JMP = 6'd12, + BR1 = 6'd0 , BR2 = 6'd22, DEC = 6'd32, + PSE1 = 6'd61, PSE2 = 6'd62, HALT = 6'd63 + } curr, next; + + always_ff @ (posedge Clk) begin + if (Reset) + curr <= HALT; + else + curr <= next; + end + + always_comb begin + + next = curr; + + LD_IR = 1'b0; + LD_PC = 1'b0; + LD_MAR = 1'b0; + LD_MDR = 1'b0; + LD_REG = 1'b0; + LD_CC = 1'b0; + LD_BEN = 1'b0; + LD_LED = 1'b0; + + GatePC = 1'b0; + GateMARMUX = 1'b0; + GateMDR = 1'b0; + GateALU = 1'b0; + + PCMUX = 2'b00; + MARMUX = 1'b0; + DRMUX = 1'b0; + SR1MUX = 1'b0; + SR2MUX = 1'b0; + ADDR1MUX = 1'b0; + ADDR2MUX = 2'b00; + ALUK = 2'b00; + + rden = 1'b0; + wren = 1'b0; + + unique case (curr) + FCH1: next = FCH2w; + FCH2w: next = FCH2x; + FCH2x: next = FCH2; + FCH2: next = FCH3; +`ifdef FETCH_DEMO + FCH3: next = PSE1; +`else + FCH3: next = DEC; +`endif + LDR1: next = LDR2w; + LDR2w: next = LDR2x; + LDR2x: next = LDR2; + LDR2: next = LDR3; + STR1: next = STR2; + STR2: next = STR3; + JSR1: next = JSR2; + ADD, AND, NOT, LDR3, STR3, + JSR2, JMP, BR2: next = FCH1; + DEC: + case (Opcode) + 4'b0001: next = ADD; + 4'b0101: next = AND; + 4'b1001: next = NOT; + 4'b0110: next = LDR1; + 4'b0111: next = STR1; + 4'b0100: next = JSR1; + 4'b1100: next = JMP; + 4'b0000: next = BR1; + 4'b1101: next = PSE1; + 4'b1111: next = HALT; + default: next = FCH1; + endcase + BR1: + if (BEN) next = BR2; + else next = FCH1; + PSE1: + if (~Continue) next = PSE1; + else next = PSE2; + PSE2: + if (Continue) next = PSE2; + else next = FCH1; + HALT: + if (Run) next = FCH1; + default: ; + endcase + + case (curr) + ADD: begin LD_REG = 1'b1; LD_CC = 1'b1; GateALU = 1'b1; DRMUX = 1'b0; SR1MUX = 1'b1; SR2MUX = IR_5; ALUK = 2'b00; end + AND: begin LD_REG = 1'b1; LD_CC = 1'b1; GateALU = 1'b1; DRMUX = 1'b0; SR1MUX = 1'b1; SR2MUX = IR_5; ALUK = 2'b01; end + NOT: begin LD_REG = 1'b1; LD_CC = 1'b1; GateALU = 1'b1; DRMUX = 1'b0; SR1MUX = 1'b1; ALUK = 2'b10; end + + LDR3: begin LD_REG = 1'b1; LD_CC = 1'b1; GateMDR = 1'b1; DRMUX = 1'b0; end + LDR1: begin LD_MAR = 1'b1; GateMARMUX = 1'b1; ADDR1MUX = 1'b1; ADDR2MUX = 2'b01; SR1MUX = 1'b1; end + STR1: begin LD_MAR = 1'b1; GateMARMUX = 1'b1; ADDR1MUX = 1'b1; ADDR2MUX = 2'b01; SR1MUX = 1'b1; end + STR2: begin LD_MDR = 1'b1; GateALU = 1'b1; SR1MUX = 1'b0; ALUK = 2'b11; end + + JMP: begin LD_PC = 1'b1; PCMUX = 2'b10; ADDR1MUX = 1'b1; ADDR2MUX = 2'b00; SR1MUX = 1'b1; end + JSR2: begin LD_PC = 1'b1; PCMUX = 2'b10; ADDR1MUX = 1'b0; ADDR2MUX = 2'b11; end + BR2: begin LD_PC = 1'b1; PCMUX = 2'b10; ADDR1MUX = 1'b0; ADDR2MUX = 2'b10; end + PSE1: begin LD_LED = 1'b1; GateMARMUX = 1'b1; MARMUX = 1'b1; end + JSR1: begin LD_REG = 1'b1; GatePC = 1'b1; DRMUX = 1'b1; end + + FCH1: begin LD_PC = 1'b1; LD_MAR = 1'b1; GatePC = 1'b1; PCMUX = 2'b00; end + FCH3: begin LD_IR = 1'b1; GateMDR = 1'b1; end + DEC: begin LD_BEN = 1'b1; end + + FCH2w, FCH2x, + LDR2w, LDR2x: begin rden = 1'b1; end + FCH2, LDR2: begin rden = 1'b1; LD_MDR = 1'b1; end + STR3: begin wren = 1'b1; end + BR1, PSE2, HALT: ; + default: ; + endcase + end + +endmodule diff --git a/lab5/src/slc3pkg.sv b/lab5/src/slc3pkg.sv new file mode 100644 index 0000000..b71f946 --- /dev/null +++ b/lab5/src/slc3pkg.sv @@ -0,0 +1,167 @@ +`ifndef _SLC3PKG_SV +`define _SLC3PKG_SV + + +package SLC3_2; + + /* opcode aliases */ + parameter op_ADD = 4'b0001; + parameter op_AND = 4'b0101; + parameter op_NOT = 4'b1001; + parameter op_BR = 4'b0000; + parameter op_JMP = 4'b1100; + parameter op_JSR = 4'b0100; + parameter op_LDR = 4'b0110; + parameter op_STR = 4'b0111; + parameter op_PSE = 4'b1101; + + /* register aliases */ + parameter R0 = 3'b000; + parameter R1 = 3'b001; + parameter R2 = 3'b010; + parameter R3 = 3'b011; + parameter R4 = 3'b100; + parameter R5 = 3'b101; + parameter R6 = 3'b110; + parameter R7 = 3'b111; + + /* branch condition aliases */ + parameter p = 3'b001; + parameter z = 3'b010; + parameter zp = 3'b011; + parameter n = 3'b100; + parameter np = 3'b101; + parameter nz = 3'b110; + parameter nzp = 3'b111; + + parameter NO_OP = 15'b0; // e.g. "never branch" + parameter outHEX = -1; + parameter inSW = -1; + + // opCLR(DR): same as DR <- DR AND DR + function [15: 0] opCLR ( input [2:0] DR ); + opCLR[15:12] = op_AND; + opCLR[11: 9] = DR; + opCLR[ 8: 6] = DR; + opCLR[ 5 ] = 1'b1; + opCLR[ 4: 0] = 5'b0; + endfunction + + // opAND(DR, SR1, SR2): DR <- SR1 AND SR2 + function [15: 0] opAND ( input [2:0] DR, SR1, SR2 ); + opAND[15:12] = op_AND; + opAND[11: 9] = DR; + opAND[ 8: 6] = SR1; + opAND[ 5: 3] = 3'b0; + opAND[ 2: 0] = SR2; + endfunction + + // opANDi(DR, SR1, imm5): DR <- SR1 AND SEXT(imm5) + function [15: 0] opANDi ( input [2:0] DR, SR, integer imm5 ); + opANDi[15:12] = op_AND; + opANDi[11: 9] = DR; + opANDi[ 8: 6] = SR; + opANDi[ 5 ] = 1'b1; + opANDi[ 4: 0] = imm5[4:0]; + endfunction + + // opADD(DR, SR1, SR2): DR <- SR1 + SR2 + function [15: 0] opADD ( input [2:0] DR, SR1, SR2 ); + opADD[15:12] = op_ADD; + opADD[11: 9] = DR; + opADD[ 8: 6] = SR1; + opADD[ 5: 3] = 3'b0; + opADD[ 2: 0] = SR2; + endfunction + + // opADDi(DR, SR1, imm5): DR <- SR1 + SEXT(imm5) + function [15: 0] opADDi ( input [2:0] DR, SR, integer imm5 ); + opADDi[15:12] = op_ADD; + opADDi[11: 9] = DR; + opADDi[ 8: 6] = SR; + opADDi[ 5 ] = 1'b1; + opADDi[ 4: 0] = imm5[4:0]; + endfunction + + // opINC(DR): same as DR <- DR + 1 + function [15: 0] opINC ( input [2:0] DR ); + opINC[15:12] = op_ADD; + opINC[11: 9] = DR; + opINC[ 8: 6] = DR; + opINC[ 5 ] = 1'b1; + opINC[ 4: 0] = 1; + endfunction + + // opINC(DR): same as DR <- DR - 1 + function [15: 0] opDEC ( input [2:0] DR ); + opDEC[15:12] = op_ADD; + opDEC[11: 9] = DR; + opDEC[ 8: 6] = DR; + opDEC[ 5 ] = 1'b1; + opDEC[ 4: 0] = 5'b11111; + endfunction + + // opNOT(DR, SR): DR <- NOT(SR) + function [15: 0] opNOT ( input [2:0] DR, SR ); + opNOT[15:12] = op_NOT; + opNOT[11: 9] = DR; + opNOT[ 8: 6] = SR; + opNOT[ 5: 0] = 5'b1; + endfunction + + // opBR(nzp, PCoffset9): if (nzp AND NZP) PC <- PC + SEXT(PCoffset9); + function [15: 0] opBR ( input [2:0] condition, integer PCoffset9 ); + opBR[15:12] = op_BR; + opBR[11: 9] = condition; + opBR[ 8: 0] = PCoffset9[8:0]; + endfunction + + // opJMP(BaseR): PC <- BaseR + function [15: 0] opJMP ( input [2:0] BaseR ); + opJMP[15:12] = op_JMP; + opJMP[11: 9] = 3'b0; + opJMP[ 8: 6] = BaseR; + opJMP[ 5: 0] = 6'b0; + endfunction + + // opRET(): same as PC <- R7 + function [15: 0] opRET ( ); + opRET[15:12] = op_JMP; + opRET[11: 9] = 3'b0; + opRET[ 8: 6] = R7; + opRET[ 5: 0] = 6'b0; + endfunction + + // opJSR(PCoffset11): R7 <- PC; PC <- PC + SEXT(PCoffset11) + function [15: 0] opJSR ( input integer PCoffset11 ); + opJSR[15:12] = op_JSR; + opJSR[11 ] = 1'b1; + opJSR[10: 0] = PCoffset11[10:0]; + endfunction + + // opLDR(DR, BaseR, offset6): DR <- M[BaseR + SEXT(offset6)] + function [15: 0] opLDR ( input [2:0] DR, BaseR, integer offset6 ); + opLDR[15:12] = op_LDR; + opLDR[11: 9] = DR; + opLDR[ 8: 6] = BaseR; + opLDR[ 5: 0] = offset6[5:0]; + endfunction + + // opSTR(SR, BaseR, offset6): M[BaseR + SEXT(offset6)] <- SR; + function [15: 0] opSTR ( input [2:0] SR, BaseR, integer offset6 ); + opSTR[15:12] = op_STR; + opSTR[11: 9] = SR; + opSTR[ 8: 6] = BaseR; + opSTR[ 5: 0] = offset6[5:0]; + endfunction + + // opPSE(ledVect12): Go to pause state and set LEDs to ledVect12 + function [15: 0] opPSE ( input [11:0] ledVect12 ); + opPSE[15:12] = op_PSE; + opPSE[11: 0] = ledVect12; + endfunction + +endpackage + + +`endif diff --git a/lab5/src/top.sv b/lab5/src/top.sv new file mode 100644 index 0000000..49a5e7e --- /dev/null +++ b/lab5/src/top.sv @@ -0,0 +1,33 @@ +`ifndef _TOP_SV +`define _TOP_SV + + +`include "utils.sv" +// `define FETCH_DEMO +// `define SIMULATION +// `define INSPECT_NET +// `define INSPECT_CTRL + +`define TOP_INTERFACE \ + input logic Run, Continue, Clk, \ + input logic [9:0] SW, \ +`ifdef SIMULATION \ + `TOGGLE_OUTPUT \ + output logic [15:0] hexval, \ +`else \ + output logic [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, \ +`endif \ + output logic [9:0] LED + +module SLC3Top (`TOP_INTERFACE); + +`ifdef SIMULATION + SLC3TopSim subject(.*); +`else + SLC3TopSynth subject(.*); +`endif + +endmodule + + +`endif diff --git a/lab5/src/topsim.sv b/lab5/src/topsim.sv new file mode 100644 index 0000000..8d53cb3 --- /dev/null +++ b/lab5/src/topsim.sv @@ -0,0 +1,20 @@ +`include "top.sv" +`include "utils.sv" + + +module SLC3TopSim (`TOP_INTERFACE); + + logic sRun, sContinue, sReset; + logic rden, wren; + logic [15:0] addr; + logic [15:0] data_from_SRAM, data_to_SRAM; + + SLC3 cpu (.*, + .Run(sRun), .Continue(sContinue), .Reset(sReset)); + MemSim mem (.Clk, + .data(data_to_SRAM), .addr(addr[9:0]), + .readout(data_from_SRAM), + .rden, .wren, .Reset(sReset)); + SyncerFSM syncer (.*); + +endmodule diff --git a/lab5/src/topsynth.sv b/lab5/src/topsynth.sv new file mode 100644 index 0000000..068d53e --- /dev/null +++ b/lab5/src/topsynth.sv @@ -0,0 +1,36 @@ +`include "top.sv" +`include "utils.sv" + + +module SLC3TopSynth (`TOP_INTERFACE); + + logic sRun, sContinue, sReset; + logic rden, wren, wren_select, wren_from_ISDU; + logic [15:0] addr, addr_init, addr_from_CPU; + logic [15:0] data_init, data_from_SRAM, data_to_SRAM, data_from_CPU; + + always_comb begin + if (wren_select) begin + wren = wren_select; + data_to_SRAM = data_init; + addr = addr_init; + end else begin + wren = wren_from_ISDU; + data_to_SRAM = data_from_CPU; + addr = addr_from_CPU; + end + end + + SLC3 cpu (.*, + .addr(addr_from_CPU), .data_to_SRAM(data_from_CPU), + .rden, .wren(wren_from_ISDU), + .Run(sRun), .Continue(sContinue), .Reset(sReset)); + MemSynth mem (.Clk, + .addr_init, .data_init, + .wren(wren_select), .Reset(sReset)); + ram ram0 (.clock(Clk), + .data(data_to_SRAM), .address(addr[9:0]), + .q(data_from_SRAM), .rden, .wren); + SyncerFSM syncer (.*); + +endmodule diff --git a/lab5/src/utils.sv b/lab5/src/utils.sv new file mode 100644 index 0000000..d4874f2 --- /dev/null +++ b/lab5/src/utils.sv @@ -0,0 +1,255 @@ +`ifndef _UTILS_SV +`define _UTILS_SV + + +`define NET_CC logic CC_N, CC_Z, CC_P, ben_in, cc_in_n, cc_in_z, cc_in_p +`define NET_MUX3 logic [2:0] drmux_out, sr1mux_out +`define NET_MUX16 logic [15:0] pcmux_out, marmux_out, mdrmux_out, sr2mux_out, addr1mux_out, addr2mux_out +`define NET_MISC logic [15:0] sr1_out, sr2_out, alu_out, bus_out, adder_out + +`define CTRL_LD logic LD_IR, LD_PC, LD_MAR, LD_MDR, LD_REG, LD_CC, LD_BEN, LD_LED +`define CTRL_GATE logic GatePC, GateMARMUX, GateMDR, GateALU +`define CTRL_MUX logic MARMUX, DRMUX, SR1MUX, SR2MUX, ADDR1MUX +`define CTRL_MUX2 logic [1:0] PCMUX, ADDR2MUX, ALUK + +`define OUTPUT_REG output [15:0] IR, PC, MAR, MDR, REG[7:0], +`define INTERNAL_REG logic [15:0] IR, PC, MAR, MDR, REG[7:0]; + +`define OUTPUT_NET \ + output `NET_CC, \ + output `NET_MUX3, \ + output `NET_MUX16, \ + output `NET_MISC, + +`define INTERNAL_NET \ + `NET_CC; \ + `NET_MUX3; \ + `NET_MUX16; \ + `NET_MISC; + +`define INPUT_CTRL \ + input `CTRL_LD, \ + input `CTRL_GATE, \ + input `CTRL_MUX, \ + input `CTRL_MUX2, + +`define OUTPUT_CTRL \ + output `CTRL_LD, \ + output `CTRL_GATE, \ + output `CTRL_MUX, \ + output `CTRL_MUX2, + +`define INTERNAL_CTRL \ + `CTRL_LD; \ + `CTRL_GATE; \ + `CTRL_MUX; \ + `CTRL_MUX2; + +`define TOGGLE_OUTPUT \ + `OUTPUT_REG \ + `ifdef INSPECT_NET \ + `OUTPUT_NET \ + `endif \ + `ifdef INSPECT_CTRL \ + `OUTPUT_CTRL \ + `endif + +`define TOGGLE_INTERNAL \ + `INTERNAL_REG \ + `ifdef INSPECT_NET \ + `INTERNAL_NET \ + `endif \ + `ifdef INSPECT_CTRL \ + `INTERNAL_CTRL \ + `endif + + +module Reg #(parameter WIDTH = 1) ( + input logic Reset, Clk, LD, + input logic [WIDTH-1:0] D, + output logic [WIDTH-1:0] Q); + + always_ff @ (posedge Clk) begin + if (Reset) Q <= 1'b0; + else if (LD) Q <= D; + end + +endmodule + + +module RegFile ( + input logic Reset, Clk, LD_REG, + input logic [2:0] SR1, SR2, DR, + input logic [15:0] in, + output logic [15:0] out1, out2, + output logic [15:0] regs[7:0]); + + always_ff @ (posedge Clk) begin + if (Reset) begin + regs[0] <= 16'b0; + regs[1] <= 16'b0; + regs[2] <= 16'b0; + regs[3] <= 16'b0; + regs[4] <= 16'b0; + regs[5] <= 16'b0; + regs[6] <= 16'b0; + regs[7] <= 16'b0; + end + if (LD_REG) regs[DR] <= in; + end + + assign out1 = regs[SR1]; + assign out2 = regs[SR2]; + +endmodule + + +module MUX2 #(parameter WIDTH) ( + input logic S, + input logic [WIDTH-1:0] in0, in1, + output logic [WIDTH-1:0] out); + + always_comb begin + case (S) + 1'b0: out = in0; + 1'b1: out = in1; + default: out = {WIDTH{1'bX}}; + endcase + end + +endmodule + + +module MUX4 #(parameter WIDTH) ( + input logic [1:0] S, + input logic [WIDTH-1:0] in0, in1, in2, in3, + output logic [WIDTH-1:0] out); + + always_comb begin + case (S) + 2'b00: out = in0; + 2'b01: out = in1; + 2'b10: out = in2; + 2'b11: out = in3; + default: out = {WIDTH{1'bX}}; + endcase + end + +endmodule + + +module ALU ( + input logic [1:0] ALUK, + input logic [15:0] A, B, + output logic [15:0] S); + + always_comb begin + case (ALUK) + 2'b00: S = A + B; + 2'b01: S = A & B; + 2'b10: S = ~A; + 2'b11: S = A; + default: S = 16'bX; + endcase + end + +endmodule + + +module Bus ( + input logic [3:0] gates, + input logic [15:0] in1, in2, in3, in4, + output logic [15:0] out); + + always_comb begin + case (gates) + 4'b1000: out = in1; + 4'b0100: out = in2; + 4'b0010: out = in3; + 4'b0001: out = in4; + default: out = 16'bX; + endcase + end + +endmodule + + +module HexDriver ( + input logic [3:0] in, + output logic [6:0] out); + + always_comb begin + unique case (in) + 4'b0000: out = 7'b1000000; + 4'b0001: out = 7'b1111001; + 4'b0010: out = 7'b0100100; + 4'b0011: out = 7'b0110000; + 4'b0100: out = 7'b0011001; + 4'b0101: out = 7'b0010010; + 4'b0110: out = 7'b0000010; + 4'b0111: out = 7'b1111000; + 4'b1000: out = 7'b0000000; + 4'b1001: out = 7'b0010000; + 4'b1010: out = 7'b0001000; + 4'b1011: out = 7'b0000011; + 4'b1100: out = 7'b1000110; + 4'b1101: out = 7'b0100001; + 4'b1110: out = 7'b0000110; + 4'b1111: out = 7'b0001110; + default: out = 7'bX; + endcase + end + +endmodule + + +module SyncerFSM ( + input logic Clk, Run, Continue, + output logic sRun, sContinue, sReset); + + enum logic [2:0] { + IDLE, RUN, CONT, RESET, + RUN_DONE, CONT_DONE, RESET_DONE + } curr, next; + + always_ff @ (posedge Clk) begin + curr <= next; + end + + always_comb begin + +`define TRANSITION(PIDLE, PRUN, PCONT, PRESET) \ + case ({~Continue, ~Run}) \ + 2'b00: next = PIDLE; \ + 2'b01: next = PRUN; \ + 2'b10: next = PCONT; \ + 2'b11: next = PRESET; \ + default: next = curr; \ + endcase + + unique case (curr) + IDLE: `TRANSITION(IDLE, RUN, CONT, RESET) + RUN: next = RUN_DONE; + CONT: next = CONT_DONE; + RESET: next = RESET_DONE; + RUN_DONE: `TRANSITION(IDLE, RUN_DONE, CONT, RESET) + CONT_DONE: `TRANSITION(IDLE, RUN, CONT_DONE, RESET) + RESET_DONE: `TRANSITION(IDLE, RESET_DONE, RESET_DONE, RESET_DONE) + default: next = IDLE; + endcase + + case (curr) + RUN: {sRun, sContinue, sReset} = 3'b100; + CONT: {sRun, sContinue, sReset} = 3'b010; + RESET: {sRun, sContinue, sReset} = 3'b001; + RUN_DONE, CONT_DONE, RESET_DONE: + {sRun, sContinue, sReset} = 3'b000; + default: {sRun, sContinue, sReset} = 3'b000; + endcase + + end + +endmodule + + +`endif