Base Design Import
Base design passed from internal simulation. Now to see how the tools handle things!
diff --git a/LICENSE b/LICENSE
index 261eeb9..d0a4662 100644
--- a/LICENSE
+++ b/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [Ryan M Price]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/Makefile b/Makefile
index b8cb5c7..a343216 100644
--- a/Makefile
+++ b/Makefile
@@ -24,8 +24,8 @@
CARAVEL_LITE?=1
# PDK switch varient
-export PDK?=sky130B
-#export PDK?=gf180mcuC
+#export PDK?=sky130B
+export PDK?=gf180mcuC
export PDKPATH?=$(PDK_ROOT)/$(PDK)
diff --git a/README.md b/README.md
index 34b9a05..2aa0193 100644
--- a/README.md
+++ b/README.md
@@ -5,8 +5,17 @@
| :exclamation: Important Note |
|-----------------------------------------|
-## Please fill in your project documentation in this README.md file
-
Refer to [README](docs/source/index.rst#section-quickstart) for a quickstart of how to use caravel_user_project
-
Refer to [README](docs/source/index.rst) for this sample project documentation.
+
+| :exclamation: Important MAKE! |
+|-----------------------------------------|
+
+This design uses design rules for the gf180mcuC PDK.
+
+This project implements a 16 bit RISC themed processor for educational purposes.
+
+Since the number of IO pins are limited the Address/Databus are merged into a single external bus.
+
+More documentation to come in the following days!
+
diff --git a/openlane/user_Minx16/config.json b/openlane/user_Minx16/config.json
new file mode 100644
index 0000000..055b66d
--- /dev/null
+++ b/openlane/user_Minx16/config.json
@@ -0,0 +1,49 @@
+{
+ "DESIGN_NAME": "Minx16Top",
+ "DESIGN_IS_CORE": 0,
+ "VERILOG_FILES": ["dir::../../verilog/rtl/defines.v", "dir::../../verilog/rtl/Minx16/*"],
+ "MACRO_PLACEMENT_CFG": "dir::macro.cfg",
+ "VERILOG_FILES_BLACKBOX": ["dir::../../verilog/rtl/gf180mcu_fd_ip_sram/gf180mcu_fd_ip_sram__sram512x8m8wm1.v"],
+ "EXTRA_LEFS": "dir::../../lef/gf180mcu_fd_ip_sram__sram512x8m8wm1.lef",
+ "EXTRA_GDS_FILES": "dir::../../gds/gf180mcu_fd_ip_sram__sram512x8m8wm1.gds",
+ "CLOCK_PERIOD": 100,
+ "CLOCK_PORT": "clk_i",
+ "CLOCK_NET": "Minx16Top.clk_i",
+ "FP_SIZING": "absolute",
+ "DIE_AREA": "0 0 2000 2000",
+ "FP_PIN_ORDER_CFG": "dir::pin_order.cfg",
+ "PL_BASIC_PLACEMENT": 0,
+ "PL_TARGET_DENSITY": 0.50,
+ "VDD_NETS": ["vccd1"],
+ "GND_NETS": ["vssd1"],
+ "DIODE_INSERTION_STRATEGY": 4,
+ "RUN_CVC": 1,
+ "pdk::sky130*": {
+ "FP_CORE_UTIL": 45,
+ "RT_MAX_LAYER": "met4",
+ "scl::sky130_fd_sc_hd": {
+ "CLOCK_PERIOD": 10
+ },
+ "scl::sky130_fd_sc_hdll": {
+ "CLOCK_PERIOD": 10
+ },
+ "scl::sky130_fd_sc_hs": {
+ "CLOCK_PERIOD": 8
+ },
+ "scl::sky130_fd_sc_ls": {
+ "CLOCK_PERIOD": 10,
+ "SYNTH_MAX_FANOUT": 5
+ },
+ "scl::sky130_fd_sc_ms": {
+ "CLOCK_PERIOD": 10
+ }
+ },
+ "pdk::gf180mcuC": {
+ "STD_CELL_LIBRARY": "gf180mcu_fd_sc_mcu7t5v0",
+ "CLOCK_PERIOD": 50.0,
+ "FP_CORE_UTIL": 40,
+ "RT_MAX_LAYER": "Metal4",
+ "SYNTH_MAX_FANOUT": 4,
+ "PL_TARGET_DENSITY": 0.45
+ }
+}
\ No newline at end of file
diff --git a/openlane/user_Minx16/macro.cfg b/openlane/user_Minx16/macro.cfg
new file mode 100644
index 0000000..d1567a8
--- /dev/null
+++ b/openlane/user_Minx16/macro.cfg
@@ -0,0 +1,4 @@
+oddMemHigh 250.0000 250.00 N
+oddMemLow 250.0000 1000.00 N
+evenMemHigh 1000.0000 250.00 N
+evenMemLow 1000.0000 1000.00 N
diff --git a/openlane/user_Minx16/pin_order.cfg b/openlane/user_Minx16/pin_order.cfg
new file mode 100644
index 0000000..603257a
--- /dev/null
+++ b/openlane/user_Minx16/pin_order.cfg
@@ -0,0 +1,76 @@
+#BUS_SORT
+
+#N
+dbus_ADBus_i\[7\]
+dbus_ADBus_o\[7\]
+dbus_ADBus_e\[7\]
+dbus_ADBus_i\[6\]
+dbus_ADBus_o\[6\]
+dbus_ADBus_e\[6\]
+dbus_ADBus_i\[5\]
+dbus_ADBus_o\[5\]
+dbus_ADBus_e\[5\]
+dbus_ADBus_i\[4\]
+dbus_ADBus_o\[4\]
+dbus_ADBus_e\[4\]
+dbus_ADBus_i\[3\]
+dbus_ADBus_o\[3\]
+dbus_ADBus_e\[3\]
+dbus_ADBus_i\[2\]
+dbus_ADBus_o\[2\]
+dbus_ADBus_e\[2\]
+dbus_ADBus_i\[1\]
+dbus_ADBus_o\[1\]
+dbus_ADBus_e\[1\]
+dbus_ADBus_i\[0\]
+dbus_ADBus_o\[0\]
+dbus_ADBus_e\[0\]
+dbus_ale_o
+dbus_ale_e
+
+#W
+dbus_dle_o
+dbus_dle_e
+dbus_stb_o\[1\]
+dbus_stb_e\[1\]
+dbus_stb_o\[0\]
+dbus_stb_e\[0\]
+dbus_rd_o
+dbus_rd_e
+dbus_wr_o
+dbus_wr_e
+dbus_rdy_i
+dbus_req_i
+dbus_ack_o
+intr_i
+inta_o
+
+#E
+dbus_ADBus_i\[8\]
+dbus_ADBus_o\[8\]
+dbus_ADBus_e\[8\]
+dbus_ADBus_i\[9\]
+dbus_ADBus_o\[9\]
+dbus_ADBus_e\[9\]
+dbus_ADBus_i\[10\]
+dbus_ADBus_o\[10\]
+dbus_ADBus_e\[10\]
+dbus_ADBus_i\[11\]
+dbus_ADBus_o\[11\]
+dbus_ADBus_e\[11\]
+dbus_ADBus_i\[12\]
+dbus_ADBus_o\[12\]
+dbus_ADBus_e\[12\]
+dbus_ADBus_i\[13\]
+dbus_ADBus_o\[13\]
+dbus_ADBus_e\[13\]
+dbus_ADBus_i\[14\]
+dbus_ADBus_o\[14\]
+dbus_ADBus_e\[14\]
+dbus_ADBus_i\[15\]
+dbus_ADBus_o\[15\]
+dbus_ADBus_e\[15\]
+rst_i
+clk_i
+nmir_i
+nmia_o
diff --git a/verilog/rtl/Minx16/Alu.v b/verilog/rtl/Minx16/Alu.v
new file mode 100644
index 0000000..07455e9
--- /dev/null
+++ b/verilog/rtl/Minx16/Alu.v
@@ -0,0 +1,54 @@
+
+module Alu (
+ input [ 3:0] op
+, input [15:0] dba
+, input [15:0] dbb
+, input ci
+, input op8
+
+, output reg [15:0] Y
+
+, output wire Co
+, output wire Zo
+, output wire Vo
+, output wire No
+);
+
+ reg C;
+ assign C8 = (( dba[7] & dbb[7]) & Y[7] ) |
+ (( dba[7] ^ dbb[7]) & ~Y[7] ) |
+ ((~dba[7] & ~dbb[7]) & Y[7] ) ;
+ assign C16 = C;
+ assign Z16 = Y == 0;
+ assign Z8 = Y[7:0] == 0;
+ assign N16 = Y[15];
+ assign N8 = Y[7];
+ assign V16 = (~Y[15]&dba[15]&dbb[15]) | (Y[15]&(~dba[15])&(~dbb[15]));
+ assign V8 = (~Y[7] &dba[7] &dbb[7]) | (Y[7] &(~dba[7]) &(~dbb[7]));
+
+ assign Co = (op8) ? C8 : C16;
+ assign Zo = (op8) ? Z8 : Z16;
+ assign No = (op8) ? N8 : N16;
+ assign Vo = (op8) ? V8 : V16;
+
+ always @*
+ case(op)
+ 4'b0000 : {C, Y} = {1'b0, 16'd0};
+ 4'b0001 : {C, Y} = {1'b0, dba};
+ 4'b0010 : {C, Y} = dba + 1'b1;
+ 4'b0011 : {C, Y} = dba - 1'b1;
+ 4'b0100 : {C, Y} = dba + dbb + 1'b0;
+ 4'b0101 : {C, Y} = dba + dbb + ci;
+ 4'b0110 : {C, Y} = dba - dbb - 1'b0;
+ 4'b0111 : {C, Y} = dba - dbb - ci;
+ 4'b1000 : {C, Y} = {1'b0, ~dba};
+ 4'b1001 : {C, Y} = {1'b0, dba & dbb};
+ 4'b1010 : {C, Y} = {1'b0, dba | dbb};
+ 4'b1011 : {C, Y} = {1'b0, dba ^ dbb};
+ 4'b1100 : {C, Y} = {dba, 1'b0};
+ 4'b1101 : {C, Y} = {dba[0], 1'b0, dba[15:1]};
+ 4'b1110 : {C, Y} = {dba, ci};
+ 4'b1111 : {C, Y} = {dba[0], ci, dba[15:1]};
+ endcase
+
+endmodule
diff --git a/verilog/rtl/Minx16/Biu16.v b/verilog/rtl/Minx16/Biu16.v
new file mode 100644
index 0000000..360130f
--- /dev/null
+++ b/verilog/rtl/Minx16/Biu16.v
@@ -0,0 +1,249 @@
+
+module Biu1616 (
+ input clk
+, input rst
+
+, input [A-1:0] core_Addr_i
+, input [D-1:0] core_Data_i
+, output reg [D-1:0] core_Data_o
+, input core_rd16
+, input core_rd8
+, input [ 1:0] core_wr
+, output reg core_rdy
+, output reg core_done
+
+, output reg [A-1:0] bus_Addr_o
+, output reg [A-1:0] bus_Addr_e
+, input [D-1:0] bus_Data_i
+, output reg [D-1:0] bus_Data_o
+, output reg [D-1:0] bus_Data_e
+, output reg [B-1:0] bus_stb_o
+, output reg [B-1:0] bus_stb_e
+, output reg bus_rd_o
+, output reg bus_rd_e
+, output reg bus_wr_o
+, output reg bus_wr_e
+, input bus_rdy_i
+
+, input bus_req_i
+, output reg bus_ack_o
+);
+
+ localparam A = 16;
+ localparam ADRENABLE = {A{1'b1}};
+ localparam ADRDISABLE = {A{1'b0}};
+
+ localparam D = 16;
+ localparam B = D / 8;
+ localparam BUSENABLE = {D{1'b0}};
+ localparam BUSDISABLE = {D{1'b1}};
+ localparam STBENABLE = {B{1'b0}};
+ localparam STBDISABLE = {B{1'b1}};
+ localparam STBACTIVE = 1'b1;
+ localparam STBINACTIVE = 1'b0;
+
+ localparam RDACTIVE = 1'b0;
+ localparam RDINACTIVE = 1'b1;
+ localparam RDENABLE = 1'b0;
+ localparam RDDISABLE = 1'b1;
+
+ localparam WRACTIVE = 1'b0;
+ localparam WRINACTIVE = 1'b1;
+ localparam WRENABLE = 1'b0;
+ localparam WRDISABLE = 1'b1;
+
+ localparam STATE_RESET = 3'b000; //
+ localparam STATE_IDLE = 3'b001; //
+ localparam STATE_16A = 3'b010; //
+ localparam STATE_16B = 3'b011; //
+ localparam STATE_16C = 3'b100; //
+ localparam STATE_16D = 3'b101; //
+ localparam STATE_BUSR = 3'b110; // Bus access was requested given
+
+ wire core_wr16 = core_wr[0] & core_wr[1];
+ wire core_wr8 = core_wr[0] ^ core_wr[1];
+
+ wire core_wrs = (core_wr[0] | core_wr[1]);
+ wire core_rds = (core_rd16 | core_rd8 );
+ wire core16 = (core_rd16 | core_wr16 );
+ wire core8 = (core_rd8 | core_wr8 );
+ wire unaligned = core_Addr_i[0] & core16;
+
+ reg [A-1:0] tAddr;
+
+ reg [2:0] pstate, nstate;
+
+ always @ (posedge clk or negedge rst)
+ if( rst == 1'b0 )
+ pstate = STATE_RESET;
+ else
+ pstate = nstate;
+
+ always @*
+ begin
+ bus_Data_o = bus_Data_o;
+ bus_Data_e = bus_Data_e;
+ bus_Addr_o = bus_Addr_o;
+ bus_Addr_e = ADRENABLE;
+ bus_ack_o = 1'b0;
+ bus_rd_o = RDINACTIVE;
+ bus_rd_e = RDENABLE;
+ bus_wr_o = WRINACTIVE;
+ bus_wr_e = WRENABLE;
+ core_rdy = 1'b0;
+ core_done = 1'b0;
+ case(pstate)
+ STATE_RESET : begin
+ tAddr = 16'h0000;
+ bus_Addr_o = 16'h0000;
+ bus_Data_o = 16'h0000;
+ bus_Data_e = BUSDISABLE;
+ core_Data_o = 16'h0000;
+ bus_stb_o = {B{STBINACTIVE}};
+ bus_stb_e = STBENABLE;
+ nstate = STATE_IDLE;
+ end
+ STATE_IDLE : begin
+ tAddr = 16'h0000;
+ bus_Addr_o = 16'h0000;
+ bus_Data_o = 16'h0000;
+ bus_Data_e = BUSDISABLE;
+ core_Data_o = 16'h0000;
+ core_rdy = 1'b1;
+ bus_stb_o = {B{STBINACTIVE}};
+ bus_stb_e = STBENABLE;
+ if( bus_req_i == 1'b1 )
+ nstate = STATE_BUSR;
+ else if( core16 | core8 )
+ begin
+ if( core_wr16 == 1'b1 & core_wr8 == 1'b0 & core_Addr_i[0] == 1'b0 )
+ begin
+ tAddr = {core_Addr_i[A-1:1], 1'b0};
+ bus_Data_o = (core_wrs) ? core_Data_i : 16'h0000;
+ bus_Data_e = BUSENABLE;
+ nstate = STATE_16A;
+ end
+ else if( core_wr16 == 1'b1 & core_wr8 == 1'b0 & core_Addr_i[0] == 1'b1)
+ begin
+ tAddr = core_Addr_i;
+ bus_Data_o = (core_wrs) ? {core_Data_i[7:0], core_Data_i[7:0]} : 16'h0000;
+ bus_Data_e = BUSENABLE;
+ nstate = STATE_16A;
+ end
+ else if( core_wr16 == 1'b0 & core_wr[1] == 1'b0 & core_wr[0] == 1'b1 )
+ begin
+ tAddr = core_Addr_i;
+ bus_Data_o = (core_wrs) ? {core_Data_i[7:0], core_Data_i[7:0]} : 16'h0000;
+ bus_Data_e = BUSENABLE;
+ nstate = STATE_16A;
+ end
+ else if( core_wr16 == 1'b0 & core_wr[1] == 1'b1 & core_wr[0] == 1'b0 )
+ begin
+ tAddr = core_Addr_i;
+ bus_Data_o = (core_wrs) ? {core_Data_i[15:8], core_Data_i[15:8]} : 16'h0000;
+ bus_Data_e = BUSENABLE;
+ nstate = STATE_16A;
+ end
+ else
+ begin
+ tAddr = core_Addr_i;
+ bus_Data_o = 0;
+ bus_Data_e = BUSENABLE;
+ nstate = STATE_16A;
+ end
+ end
+ else
+ nstate = STATE_IDLE;
+ end
+ STATE_16A : begin
+ if( core16 & core_Addr_i[0] == 1'b0)
+ bus_stb_o = {B{STBACTIVE}};
+ else
+ bus_stb_o = { ( tAddr[0]) ? STBACTIVE : STBINACTIVE,
+ (~tAddr[0]) ? STBACTIVE : STBINACTIVE};
+ bus_stb_e = STBENABLE;
+ bus_Addr_o = tAddr;
+ bus_rd_o = (core_rds) ? RDACTIVE : RDINACTIVE;
+ bus_wr_o = (core_wrs) ? WRACTIVE : WRINACTIVE;
+ nstate = STATE_16B;
+ end
+ STATE_16B : begin
+ if( core_rd16 == 1'b1 & core_Addr_i[0] == 1'b0 )
+ core_Data_o = bus_Data_i;
+ else if( bus_stb_o[1] )
+ core_Data_o = bus_Data_i[15:8];
+ else
+ core_Data_o = bus_Data_i[7:0];
+ bus_stb_o = bus_stb_o;
+ bus_stb_e = STBENABLE;
+ bus_rd_o = (core_rds) ? RDACTIVE : RDINACTIVE;
+ bus_wr_o = (core_wrs) ? WRACTIVE : WRINACTIVE;
+ if( bus_rdy_i == 1'b1 & unaligned == 1'b1 )
+ begin
+ tAddr = tAddr + 1;
+ nstate = STATE_16C;
+ core_done = 1'b0;
+ end
+ else if( bus_rdy_i == 1'b1 & unaligned == 1'b0 )
+ begin
+ nstate = STATE_IDLE;
+ core_done = 1'b1;
+ end
+ else
+ begin
+ nstate = STATE_16B;
+ core_done = 1'b0;
+ end
+ end
+ STATE_16C : begin
+ if( core_wrs )
+ begin
+ bus_Data_o = {8'h00, core_Data_i[15:8]};
+ bus_Data_e = BUSENABLE;
+ end
+ else
+ begin
+ bus_Data_o = 0;
+ bus_Data_e = BUSDISABLE;
+ end
+ bus_Addr_o = tAddr;
+ bus_stb_o = {STBINACTIVE, STBACTIVE};
+ bus_stb_e = STBENABLE;
+ bus_rd_o = (core_rds) ? RDACTIVE : RDINACTIVE;
+ bus_wr_o = (core_wrs) ? WRACTIVE : WRINACTIVE;
+ nstate = STATE_16D;
+ end
+ STATE_16D : begin
+ core_Data_o[15:8] = bus_Data_i[7:0];
+ bus_stb_o = bus_stb_o;
+ bus_stb_e = STBENABLE;
+ bus_rd_o = (core_rds) ? RDACTIVE : RDINACTIVE;
+ bus_wr_o = (core_wrs) ? WRACTIVE : WRINACTIVE;
+ core_done = bus_rdy_i;
+ if( bus_rdy_i == 1'b1 )
+ nstate = STATE_IDLE;
+ else
+ nstate = STATE_16D;
+ end
+ STATE_BUSR : begin
+ bus_Addr_e = ADRDISABLE;
+ bus_Data_e = BUSDISABLE;
+ bus_stb_o = STBINACTIVE;
+ bus_stb_o = STBDISABLE;
+ bus_rd_o = RDINACTIVE;
+ bus_rd_e = RDDISABLE;
+ bus_wr_o = WRINACTIVE;
+ bus_wr_e = WRDISABLE;
+ bus_ack_o = 1'b1;
+ if( bus_req_i == 1'b1 )
+ nstate = STATE_BUSR;
+ else
+ nstate = STATE_IDLE;
+ end
+ default : begin
+ nstate = STATE_RESET;
+ end
+ endcase
+ end
+
+endmodule
diff --git a/verilog/rtl/Minx16/Controller.v b/verilog/rtl/Minx16/Controller.v
new file mode 100644
index 0000000..6a190e1
--- /dev/null
+++ b/verilog/rtl/Minx16/Controller.v
@@ -0,0 +1,537 @@
+
+module Controller (
+ input clk
+, input rst
+
+, input intr_i
+, output reg inta
+, input nmir
+, output reg nmia
+, input trap
+, output reg trapa
+
+, input [15:0] ir
+, input status
+, input done
+
+, output reg ldIr
+, output reg ldSp
+, output reg incSp
+, output reg decSp
+, output reg ldPc
+, output reg incPc
+
+, output reg rd16
+, output reg rd8
+, output reg [ 1:0] wr
+
+, output reg [ 2:0] addrSel
+, output reg [ 2:0] dataSel
+, output reg [ 2:0] trapSel
+, output reg [ 2:0] ra
+, output reg [ 2:0] rb
+, output reg [ 2:0] rd
+, output reg [ 2:0] wd
+, output reg [ 3:0] aluop
+, output reg [ 3:0] flagCond
+, output reg flagSave
+, output reg flagRest
+, output reg op8
+);
+
+ reg irqA = 0;
+ wire intr = intr_i & irqA;
+ reg dbg_invalidop = 0;
+
+ // [15:13] [12:9][8:6][5:3][2:0] ALU16 with top bits == 3'b000? alu 16 bit
+ // [15:13] [12:9][8:6][5:3][2:0] ALU16 with top bits == 3'b001? alu 8h bit
+ // [15:13] [12:9][8:6][5:3][2:0] ALU16 with top bits == 3'b010? alu 8l bit
+ // [15:13] [12:9][8:6][5:3][2:0] MEMORY with top bits == 3'b011? alu slot can diff read/write, 16 or 8 bit
+ // [15:13] [12:9][8:6][5:3][2:0] JUMP with top bits == 3'b100? alu slot can diff conditions
+ // [15:13] [12:9][8:6][5:3][2:0] FREE with top bits == 3'b1xx?
+
+ wire [2:0] majorOp = ir[15:13];
+ wire [3:0] minorOp = ir[12: 9];
+
+ reg [3:0] pstate, nstate;
+ always @ (posedge clk or negedge rst)
+ if( rst == 1'b0 )
+ pstate = 0;
+ else
+ pstate = nstate;
+
+ always @*
+ begin
+ if( rst == 1'b0 )
+ irqA = 0;
+ dbg_invalidop = 1'b0;
+ inta = 1'b0;
+ nmia = 1'b0;
+ trapa = 1'b0;
+ trapSel = 3'b000;
+
+ ldIr = 1'b0;
+ ldSp = 1'b0;
+ incSp = 1'b0;
+ decSp = 1'b0;
+ ldPc = 1'b0;
+ incPc = 1'b0;
+ op8 = 1'b0;
+
+ rd16 = 1'b0;
+ rd8 = 1'b0;
+ wr = 2'b00;
+
+ addrSel = 3'b000;
+ dataSel = 3'b000;
+ ra = 3'b000;
+ rb = 3'b000;
+ rd = 3'b000;
+ wd = 3'b000;
+ aluop = 4'b0000;
+ flagCond = 1'b0;
+ flagSave = 1'b0;
+ flagRest = 1'b0;
+ case(pstate)
+ 4'b0000 : begin
+ addrSel = 3'b000;
+ rd16 = 1'b1;
+ ldIr = 1'b1;
+ incPc = done;
+ if( done == 1'b1 )
+ nstate = 4'b0001;
+ else
+ nstate = 4'b0000;
+ end
+ 4'b0001 : begin
+ nstate = 4'b1111;
+ case(majorOp)
+ 3'b000 : begin //Alu 16 bit
+ flagSave = 1'b1;
+ dataSel = 3'b001;
+ aluop = minorOp;
+ ra = ir[ 8:6];
+ rb = ir[ 5:3];
+ rd = ir[ 2:0];
+ wd = 3'b011;
+ nstate = 4'b1111;
+ end
+ 3'b001 : begin //Alu 8 bit high
+ flagSave = 1'b1;
+ dataSel = 3'b001;
+ aluop = minorOp;
+ ra = ir[ 8:6];
+ rb = ir[ 5:3];
+ rd = ir[ 2:0];
+ wd = 3'b010;
+ nstate = 4'b1111;
+ end
+ 3'b010 : begin //Alu 8 bit low
+ flagSave = 1'b1;
+ dataSel = 3'b001;
+ aluop = minorOp;
+ ra = ir[ 8:6];
+ rb = ir[ 5:3];
+ rd = ir[ 2:0];
+ wd = 3'b001;
+ op8 = 1'b1;
+ nstate = 4'b1111;
+ end
+ 3'b011 : begin //Memory operations
+ nstate = 4'b1111;
+ case(minorOp)
+ 4'b0000 : begin //16 bit read
+ rd16 = 1'b1;
+ ra = ir[8:6];
+ rb = ir[5:3];
+ rd = ir[2:0];
+ wd = 3'b011;
+ dataSel = 3'b000;
+ addrSel = ir[5:3];
+ if( done )
+ nstate = 4'b1111;
+ else
+ nstate = 4'b0001;
+ end
+ 4'b0001 : begin //16 bit write
+ wr = 2'b11;
+ rb = ir[5:3];
+ ra = ir[2:0];
+ dataSel = 3'b011;
+ addrSel = ir[8:6];
+ if( done )
+ nstate = 4'b1111;
+ else
+ nstate = 4'b0001;
+ end
+ 4'b0010 : begin //8 bit read low
+ rd8 = 1'b1;
+ ra = ir[8:6];
+ rb = ir[5:3];
+ rd = ir[2:0];
+ wd = 3'b001;
+ dataSel = 3'b000;
+ addrSel = ir[5:3];
+ if( done )
+ nstate = 4'b1111;
+ else
+ nstate = 4'b0001;
+ end
+ 4'b0011 : begin //8 bit write low
+ wr = 2'b01;
+ rb = ir[5:3];
+ ra = ir[2:0];
+ dataSel = 3'b011;
+ addrSel = ir[8:6];
+ if( done )
+ nstate = 4'b1111;
+ else
+ nstate = 4'b0001;
+ end
+ 4'b0100 : begin //8 bit read high
+ rd8 = 1'b1;
+ ra = ir[8:6];
+ rb = ir[5:3];
+ rd = ir[2:0];
+ wd = 3'b110;
+ dataSel = 3'b000;
+ addrSel = ir[5:3];
+ if( done )
+ nstate = 4'b1111;
+ else
+ nstate = 4'b0001;
+ end
+ 4'b0101 : begin //8 bit write high
+ wr = 2'b10;
+ rb = ir[5:3];
+ ra = ir[2:0];
+ dataSel = 3'b011;
+ addrSel = ir[8:6];
+ if( done )
+ nstate = 4'b1111;
+ else
+ nstate = 4'b0001;
+ end
+ 4'b0110 : begin //8 Bit read and save sign extend
+ rd8 = 1'b1;
+ ra = ir[8:6];
+ rb = ir[5:3];
+ rd = ir[2:0];
+ wd = 3'b011;
+ dataSel = 3'b101;
+ addrSel = ir[5:3];
+ if( done )
+ nstate = 4'b1111;
+ else
+ nstate = 4'b0001;
+ end
+ 4'b0111 : begin //Load 8 bit sign extended immediate into register
+ rd = {2'b00, ir[8]};
+ wd = 3'b011;
+ dataSel = 3'b111;
+ nstate = 4'b1111;
+ end
+ 4'b1000 : begin //8 Bit immediate load
+ rd = ir[10:8];
+ wd = {1'b0, ir[11], ~ir[11]};
+ dataSel = 3'b110;
+ nstate = 4'b1111;
+ end
+ 4'b1001 : begin
+ rd = ir[10:8];
+ wd = {1'b0, ir[11], ~ir[11]};
+ dataSel = 3'b110;
+ nstate = 4'b1111;
+ end
+ 4'b1010 : begin
+ rd = ir[10:8];
+ wd = {1'b0, ir[11], ~ir[11]};
+ dataSel = 3'b110;
+ nstate = 4'b1111;
+ end
+ 4'b1011 : begin
+ rd = ir[10:8];
+ wd = {1'b0, ir[11], ~ir[11]};
+ dataSel = 3'b110;
+ nstate = 4'b1111;
+ end
+ 4'b1100 : begin
+ rd = ir[10:8];
+ wd = {1'b0, ir[11], ~ir[11]};
+ dataSel = 3'b110;
+ nstate = 4'b1111;
+ end
+ 4'b1101 : begin
+ rd = ir[10:8];
+ wd = {1'b0, ir[11], ~ir[11]};
+ dataSel = 3'b110;
+ nstate = 4'b1111;
+ end
+ 4'b1110 : begin
+ rd = ir[10:8];
+ wd = {1'b0, ir[11], ~ir[11]};
+ dataSel = 3'b110;
+ nstate = 4'b1111;
+ end
+ 4'b1111 : begin
+ rd = ir[10:8];
+ wd = {1'b0, ir[11], ~ir[11]};
+ dataSel = 3'b110;
+ nstate = 4'b1111;
+ end
+ endcase
+ end
+ 3'b100 : begin //Jump and Call
+ flagCond = minorOp;
+ if( ir[8] ) //Call instruction
+ begin
+ if( status )
+ begin
+ //Save PC
+ wr = 2'b11;
+ if( ~(minorOp == 4'b1111) )
+ trapSel = 3'b111;
+ else
+ trapSel = 3'b000;
+ dataSel = 3'b010;
+ addrSel = 3'b101;
+ decSp = done;
+ if( done )
+ nstate = 4'b1000;
+ else
+ nstate = 4'b0001;
+ end
+ else
+ nstate = 4'b1111;
+ end
+ else //Jump instruction
+ begin
+ if( status & ~(minorOp == 4'b1111))
+ begin
+ rd16 = 1'b1;
+ dataSel = 3'b000;
+ addrSel = 3'b000;
+ ldPc = done;
+ if( done )
+ nstate = 4'b1111;
+ else
+ nstate = 4'b0001;
+ end
+ else if( status & (minorOp == 4'b1111))
+ begin
+ ra = ir[7:5];
+ dataSel = 3'b011;
+ ldPc = 1'b1;
+ nstate = 4'b1111;
+ end
+ else
+ begin
+ incPc = 1'b1;
+ nstate = 4'b1111;
+ end
+ end
+ end
+ 3'b101 : begin //Call
+ nstate = 4'b1111;
+ end
+ 3'b110 : begin //Free
+ nstate = 4'b1111;
+ end
+ 3'b111 : begin //Special Operations
+ nstate = 4'b1111;
+ case(minorOp)
+ 4'b0000 : begin //Load SP
+ if( ir[8] == 1'b1 )
+ begin
+ ldSp = 1'b1;
+ dataSel = 3'b111;
+ nstate = 4'b1111;
+ end
+ else
+ begin
+ rd16 = 1'b1;
+ dataSel = 3'b000;
+ addrSel = 3'b000;
+ ldSp = 1'b1;
+ incPc = done;
+ if( done )
+ nstate = 4'b1111;
+ else
+ nstate = 4'b0001;
+ end
+ end
+ 4'b0001 : begin //Set Flag
+ if( ir[8] == 1'b1 )
+ irqA = 1'b1;
+ else
+ irqA = 1'b0;
+ nstate = 4'b1111;
+ end
+ 4'b1110 : begin //return from interrupt
+ flagCond = ir[7:4];
+ if( status )
+ begin
+ incSp = 1'b1;
+ nstate = 4'b1010; //Load Flags from stack then PC
+ end
+ else
+ begin
+ nstate = 4'b1111;
+ end
+ end
+ 4'b1111 : begin //return
+ flagCond = ir[7:4];
+ if( status )
+ begin
+ incSp = 1'b1;
+ nstate = 4'b1001; //Load PC from stack
+ end
+ else
+ begin
+ nstate = 4'b1111;
+ end
+ end
+ default : nstate = 4'b1111;
+ endcase
+ end
+ endcase
+ end
+ 4'b0010 : begin // jump operation
+ nstate = 4'b1111;
+ end
+ 4'b0011 : begin
+ nstate = 4'b1111;
+ end
+ 4'b0100 : begin
+ nstate = 4'b1111;
+ end
+ 4'b0101 : begin
+ nstate = 4'b1111;
+ end
+ 4'b0110 : begin
+ nstate = 4'b1111;
+ end
+ 4'b1000 : begin // Finish Call by loading PC from selected destination
+ if( ~(minorOp == 4'b1111))
+ begin
+ rd16 = 1'b1;
+ dataSel = 3'b000;
+ addrSel = 3'b000;
+ ldPc = done;
+ if( done )
+ nstate = 4'b1111;
+ else
+ nstate = 4'b1000;
+ end
+ else if(minorOp == 4'b1111)
+ begin
+ ra = ir[7:5];
+ dataSel = 3'b011;
+ ldPc = 1'b1;
+ nstate = 4'b1111;
+ end
+ else
+ begin
+ incPc = 1'b1;
+ nstate = 4'b1111;
+ end
+ end
+ 4'b1001 : begin //Read from stack PC
+ rd16 = 1'b1;
+ ldPc = 1'b1;
+ addrSel = 3'b101;
+ dataSel = 3'b000;
+ if( done )
+ nstate = 4'b1111;
+ else
+ nstate = 4'b1001;
+ end
+ 4'b1010 : begin //Read from stack PC
+ rd16 = 1'b1;
+ ldPc = 1'b1;
+ addrSel = 3'b101;
+ dataSel = 3'b000;
+ if( done )
+ nstate = 4'b1011;
+ else
+ nstate = 4'b1010;
+ end
+ 4'b1011 : begin //Read from stack Flags
+ rd16 = 1'b1;
+ flagRest = 1'b1;
+ addrSel = 3'b101;
+ dataSel = 3'b000;
+ incSp = done;
+ if( done )
+ nstate = 4'b1111;
+ else
+ nstate = 4'b1011;
+ end
+ 4'b1100 : begin //Interrupts! Save PC
+ trapSel = 3'b000;
+ wr = 2'b11;
+ dataSel = 3'b010;
+ addrSel = 3'b101;
+ decSp = done;
+ if( done )
+ nstate = 4'b1101;
+ else
+ nstate = 4'b1100;
+ end
+ 4'b1101 : begin //Load PC
+ dataSel = 3'b010;
+ addrSel = 3'b101;
+ if ( trap == 1'b1 )
+ trapSel = 3'b001;
+ else if( nmir == 1'b1 )
+ trapSel = 3'b010;
+ else if( intr == 1'b1 )
+ trapSel = 3'b011;
+ else
+ trapSel = 3'b000;
+ nstate = 4'b1110;
+ end
+ 4'b1110 : begin //Load PC
+ ldPc = 1'b1;
+ dataSel = 3'b010;
+ addrSel = 3'b101;
+ if ( trap == 1'b1 )
+ begin
+ trapSel = 3'b001;
+ trapa = 1'b1;
+ end
+ else if( nmir == 1'b1 )
+ begin
+ trapSel = 3'b010;
+ nmia = 1'b1;
+ end
+ else if( intr == 1'b1 )
+ begin
+ trapSel = 3'b011;
+ inta = 1'b1;
+ end
+ else
+ trapSel = 3'b000;
+ nstate = 4'b0000;
+ end
+ 4'b1111 : begin //Int ack
+ if( trap == 1'b1 | nmir == 1'b1 | intr == 1'b1 )
+ begin
+ wr = 2'b11;
+ trapSel = 3'b000;
+ dataSel = 3'b100;
+ addrSel = 3'b101;
+ decSp = done;
+ if( done )
+ nstate = 4'b1100;
+ else
+ nstate = 4'b1111;
+ end
+ else
+ nstate = 4'b0000;
+ end
+ default : nstate = 4'b0000;
+ endcase
+ end
+
+endmodule
diff --git a/verilog/rtl/Minx16/FlagRegister.v b/verilog/rtl/Minx16/FlagRegister.v
new file mode 100644
index 0000000..e231dee
--- /dev/null
+++ b/verilog/rtl/Minx16/FlagRegister.v
@@ -0,0 +1,99 @@
+
+module FlagRegister (
+ input clk
+, input rst
+
+, input [3:0] flagCond
+, output reg status
+
+, input LD
+, input flagRest
+
+, input Ci
+, input Ni
+, input Zi
+, input Vi
+
+, input Cbk
+, input Nbk
+, input Zbk
+, input Vbk
+
+, output reg Co
+, output reg No
+, output reg Zo
+, output reg Vo
+);
+
+ always @ (posedge clk or negedge rst)
+ begin
+ if( rst == 1'b0 )
+ Co <= 1'b0;
+ else if (LD == 1'b1)
+ Co <= Ci;
+ else if (flagRest == 1'b1)
+ Co <= Cbk;
+ else
+ Co <= Co;
+ end
+
+ always @ (posedge clk or negedge rst)
+ begin
+ if( rst == 1'b0 )
+ Vo <= 1'b0;
+ else if (LD == 1'b1)
+ Vo <= Vi;
+ else if (flagRest == 1'b1)
+ Vo <= Vbk;
+ else
+ Vo <= Vo;
+ end
+
+ always @ (posedge clk or negedge rst)
+ begin
+ if( rst == 1'b0 )
+ No <= 1'b0;
+ else if (LD == 1'b1)
+ No <= Ni;
+ else if (flagRest == 1'b1)
+ No <= Nbk;
+ else
+ No <= No;
+ end
+
+ always @ (posedge clk or negedge rst)
+ begin
+ if( rst == 1'b0 )
+ Zo <= 1'b0;
+ else if (LD == 1'b1)
+ Zo <= Zi;
+ else if (flagRest == 1'b1)
+ Zo <= Zbk;
+ else
+ Zo <= Zo;
+ end
+
+ // 7 5 3 1
+ //({C16, C8, Z16, Z8, V16, V8, N16, N8})
+ always @*
+ case(flagCond)
+ 4'b0000 : status = 1'b0;
+ 4'b0001 : status = 1'b1;
+ 4'b0010 : status = Zo; // Zero
+ 4'b0011 : status = ~Zo; //~Zero
+ 4'b0100 : status = Co; // Carry
+ 4'b0101 : status = ~Co; //~Carry
+ 4'b0110 : status = Vo; // Overflow
+ 4'b0111 : status = ~Vo; //~Overflow
+ 4'b1000 : status = No; // minus
+ 4'b1001 : status = ~No; // plus
+ 4'b1010 : status = (~No & ~Vo) | ( No & Vo); //greather than or equal
+ 4'b1011 : status = ( No & ~Vo) | (~No & Vo); //Less than
+ 4'b1100 : status = ~Zo & ((~No & ~Vo) | ( No & Vo)); // greather than
+ 4'b1101 : status = Zo & (( No & ~Vo) | (~No & Vo)); // less than or equal
+ 4'b1110 : status = 1'b0;
+ 4'b1111 : status = 1'b1;
+ endcase
+
+
+endmodule
diff --git a/verilog/rtl/Minx16/Minx16Cpu.v b/verilog/rtl/Minx16/Minx16Cpu.v
new file mode 100644
index 0000000..25ee9d4
--- /dev/null
+++ b/verilog/rtl/Minx16/Minx16Cpu.v
@@ -0,0 +1,246 @@
+
+module Minx16Cpu (
+ input clk_i
+, input rst_i
+
+, output wire [15:0] dbus_Addr_o
+, output wire [15:0] dbus_Addr_e
+, input [15:0] dbus_Data_i
+, output wire [15:0] dbus_Data_o
+, output wire [15:0] dbus_Data_e
+, output wire [ 1:0] dbus_stb_o
+, output wire [ 1:0] dbus_stb_e
+, output wire dbus_rd_o
+, output wire dbus_rd_e
+, output wire dbus_wr_o
+, output wire dbus_wr_e
+, input dbus_rdy_i
+
+, input dbus_req_i
+, output wire dbus_ack_o
+
+, input intr_i
+, output wire inta_o
+, input nmir_i
+, output wire nmia_o
+);
+
+ wire clk = clk_i;
+ wire rst = rst_i;
+
+ reg [15:0] databus;
+ reg [15:0] core_Addr;
+ wire [15:0] core_Data_o;
+ wire core_rd16;
+ wire core_rd8;
+ wire [ 1:0] core_wr;
+ wire core_rdy;
+ wire core_done;
+
+ wire [15:0] wpc, pc, sp, ir;
+ wire [15:0] alu;
+ wire ldIr;
+ wire ldSp;
+ wire incSp;
+ wire decSp;
+ wire ldPc;
+ wire incPc;
+ wire [ 2:0] addrSel;
+ wire [ 2:0] dataSel;
+ wire [ 2:0] ra, rb;
+ wire [15:0] da, db;
+ wire [ 2:0] rd, wd;
+ wire [ 3:0] aluOp;
+ wire [ 3:0] flagCond;
+ wire flagSave;
+ wire [ 2:0] trapSel;
+ wire Ci, Co, Zo, No, Vo, op8, status;
+
+ //Nothing trapping this build iteration
+ wire trap = 1'b0;
+ wire trapa;
+
+ Biu1616 busUnit (
+ .clk(clk)
+ , .rst(rst)
+
+ , .core_Addr_i(core_Addr )
+ , .core_Data_i(databus )
+ , .core_Data_o(core_Data_o)
+ , .core_rd16 (core_rd16 )
+ , .core_rd8 (core_rd8 )
+ , .core_wr (core_wr )
+ , .core_rdy (core_rdy )
+ , .core_done (core_done )
+
+ , .bus_Addr_o (dbus_Addr_o)
+ , .bus_Addr_e (dbus_Addr_e)
+ , .bus_Data_i (dbus_Data_i)
+ , .bus_Data_o (dbus_Data_o)
+ , .bus_Data_e (dbus_Data_e)
+ , .bus_stb_o (dbus_stb_o )
+ , .bus_stb_e (dbus_stb_e )
+ , .bus_rd_o (dbus_rd_o )
+ , .bus_rd_e (dbus_rd_e )
+ , .bus_wr_o (dbus_wr_o )
+ , .bus_wr_e (dbus_wr_e )
+ , .bus_rdy_i (dbus_rdy_i )
+
+ , .bus_req_i (dbus_req_i )
+ , .bus_ack_o (dbus_ack_o )
+ );
+
+ Alu computationCenter (
+ .op (aluOp)
+ , .dba(da)
+ , .dbb(db)
+ , .ci (Ci)
+ , .op8(op8)
+ , .Y (alu)
+ , .Co (Co)
+ , .Zo (Zo)
+ , .Vo (Vo)
+ , .No (No)
+ );
+
+ RegFile16 #(3) cpuRegs (
+ .clk(clk)
+ , .rst(rst)
+
+ , .ra(ra)
+ , .da(da)
+
+ , .rb(rb)
+ , .db(db)
+
+ , .rd(rd)
+ , .dd(databus)
+ , .wd(wd)
+ );
+
+ StackPointer #(16) spReg (
+ .clk(clk)
+ , .rst(rst)
+
+ , .LD(ldSp)
+ , .INC(incSp)
+ , .DEC(decSp)
+ , .D(databus)
+ , .Q(sp)
+ );
+
+ ProgramCounter #(16) pcReg (
+ .clk(clk)
+ , .rst(rst)
+
+ , .LD(ldPc)
+ , .INC(incPc)
+ , .D(databus)
+ , .Q(pc)
+ );
+
+ Register #(16) irReg (
+ .clk(clk)
+ , .rst(rst)
+
+ , .LD(ldIr)
+ , .D(databus)
+ , .Q(ir)
+ );
+
+ FlagRegister frReg (
+ .clk(clk)
+ , .rst(rst)
+
+ , .flagCond(flagCond)
+ , .status (status)
+ , .LD (flagSave)
+ , .flagRest(flagRest)
+ , .Ci (Co)
+ , .Ni (No)
+ , .Vi (Vo)
+ , .Zi (Zo)
+
+ , .Cbk (databus[3])
+ , .Zbk (databus[2])
+ , .Nbk (databus[1])
+ , .Vbk (databus[0])
+ , .Co (Ci)
+ , .Zo (Zi)
+ , .No (Ni)
+ , .Vo (Vi)
+ );
+
+ Controller brain (
+ .clk(clk)
+ , .rst(rst)
+
+ , .trap (trap)
+ , .trapa (trapa)
+ , .intr_i (intr_i)
+ , .inta (inta_o)
+ , .nmir (nmir_i)
+ , .nmia (nmia_o)
+
+ , .ir(ir)
+ , .status(status)
+ , .done(core_done | 1'b0 ) // Combinatorial (misinterpretation) of icarus verilog.. seems to break all if two fsms
+ // communcate with each other. this shouldn't fix it but it does.. LOL
+
+ , .ldIr (ldIr)
+ , .ldSp (ldSp)
+ , .incSp(incSp)
+ , .decSp(decSp)
+ , .ldPc (ldPc)
+ , .incPc(incPc)
+
+ , .rd16 (core_rd16)
+ , .rd8 (core_rd8 )
+ , .wr (core_wr )
+
+ , .addrSel (addrSel)
+ , .dataSel (dataSel)
+ , .ra (ra)
+ , .rb (rb)
+ , .rd (rd)
+ , .wd (wd)
+ , .aluop (aluOp)
+ , .op8 (op8)
+ , .flagCond(flagCond)
+ , .flagRest(flagRest)
+ , .flagSave(flagSave)
+ , .trapSel (trapSel )
+ );
+
+ always @*
+ case(addrSel)
+ 3'b000 : core_Addr = pc;
+ 3'b001 : core_Addr = pc;
+ 3'b010 : core_Addr = da; //Register?
+ 3'b011 : core_Addr = db;
+ 3'b100 : core_Addr = pc + da;
+ 3'b101 : core_Addr = sp;
+ 3'b110 : core_Addr = 16'h0001;
+ 3'b111 : core_Addr = 16'h0000;
+ endcase
+
+ trapAddr trapHandles(
+ .trapSel(trapSel)
+ , .pc(pc)
+ , .cpc(wpc)
+ );
+
+ //dataMux datMux(databus, dataSel, core_Data_o, alu, pc, da);
+ always @*
+ case(dataSel)
+ 3'b000 : databus = core_Data_o;
+ 3'b001 : databus = alu;
+ 3'b010 : databus = wpc;
+ 3'b011 : databus = da;
+ 3'b100 : databus = {12'h000, Ci, Zi, Ni, Vi};
+ 3'b101 : databus = {{8{core_Data_o[7]}}, core_Data_o[7:0] };
+ 3'b110 : databus = { ir[7:0], ir[7:0]};
+ 3'b111 : databus = {{8{ir[7]}}, ir[7:0]}; //Sign extend
+ endcase
+
+endmodule
diff --git a/verilog/rtl/Minx16/Minx16Top.v b/verilog/rtl/Minx16/Minx16Top.v
new file mode 100644
index 0000000..e844260
--- /dev/null
+++ b/verilog/rtl/Minx16/Minx16Top.v
@@ -0,0 +1,128 @@
+
+module Minx16Top (
+ input clk_i
+, input rst_i
+
+, input [15:0] dbus_ADBus_i
+, output wire [15:0] dbus_ADBus_o
+, output wire [15:0] dbus_ADBus_e
+, output wire dbus_ale_o
+, output wire dbus_ale_e
+, output wire dbus_dle_o
+, output wire dbus_dle_e
+, output wire [ 1:0] dbus_stb_o
+, output wire [ 1:0] dbus_stb_e
+, output wire dbus_rd_o
+, output wire dbus_rd_e
+, output wire dbus_wr_o
+, output wire dbus_wr_e
+, input dbus_rdy_i
+
+, input dbus_req_i
+, output wire dbus_ack_o
+
+, input intr_i
+, output wire inta_o
+, input nmir_i
+, output wire nmia_o
+);
+
+ wire [15:0] core_Addr_i;
+ wire [15:0] core_Data_i;
+ wire [15:0] core_Data_o;
+ wire [ 1:0] core_stb_o;
+ wire core_rd_o;
+ wire core_wr_o;
+ wire core_rdy_i;
+
+ wire [15:0] scb_Addr_o;
+ wire [15:0] scb_Data_i;
+ wire [15:0] scb_Data_o;
+ wire [ 1:0] scb_stb_o;
+ wire scb_ce_o;
+ wire scb_rd_o;
+ wire scb_wr_o;
+ wire scb_rdy_i;
+
+ Minx16Cpu cpu (
+ .clk_i (clk_i)
+ , .rst_i (rst_i)
+
+ , .intr_i (intr_i)
+ , .inta_o (inta_o)
+ , .nmir_i (nmir_i)
+ , .nmia_o (nmia_o)
+
+ , .dbus_Addr_o (core_Addr_i)
+ , .dbus_Addr_e ()
+ , .dbus_Data_i (core_Data_o)
+ , .dbus_Data_o (core_Data_i)
+ , .dbus_Data_e ()
+ , .dbus_stb_o (core_stb_o)
+ , .dbus_stb_e ()
+ , .dbus_rd_o (core_rd_o)
+ , .dbus_rd_e ()
+ , .dbus_wr_o (core_wr_o)
+ , .dbus_wr_e ()
+ , .dbus_rdy_i (core_rdy_i | 1'b0)
+
+ , .dbus_req_i (dbus_req_i)
+ , .dbus_ack_o ()
+ );
+
+ MinxFoldedBus1616 biu (
+ .clk_i(clk_i)
+ , .rst_i(rst_i)
+
+ , .core_Addr_i(core_Addr_i)
+ , .core_Data_i(core_Data_i)
+ , .core_Data_o(core_Data_o)
+ , .core_stb_i(core_stb_o)
+ , .core_rd_i(core_rd_o)
+ , .core_wr_i(core_wr_o)
+ , .core_rdy_o(core_rdy_i)
+
+ , .scb_Addr_o(scb_Addr_o)
+ , .scb_Data_i(scb_Data_o)
+ , .scb_Data_o(scb_Data_i)
+ , .scb_stb_o (scb_stb_o)
+ , .scb_ce_o (scb_ce_o)
+ , .scb_rd_o (scb_rd_o)
+ , .scb_wr_o (scb_wr_o)
+ , .scb_rdy_i (scb_rdy_i)
+
+ , .dbus_ADBus_i(dbus_ADBus_i)
+ , .dbus_ADBus_o(dbus_ADBus_o)
+ , .dbus_ADBus_e(dbus_ADBus_e)
+ , .dbus_ale_o (dbus_ale_o)
+ , .dbus_ale_e (dbus_ale_e)
+ , .dbus_dle_o (dbus_dle_o)
+ , .dbus_dle_e (dbus_dle_e)
+ , .dbus_stb_o (dbus_stb_o)
+ , .dbus_stb_e (dbus_stb_e)
+ , .dbus_rd_o (dbus_rd_o)
+ , .dbus_rd_e (dbus_rd_e)
+ , .dbus_wr_o (dbus_wr_o)
+ , .dbus_wr_e (dbus_wr_e)
+ , .dbus_rdy_i (dbus_rdy_i)
+
+ , .dbus_req_i (dbus_req_i)
+ , .dbus_ack_o (dbus_ack_o)
+ );
+
+ //Block of fast memory
+ SCB_memory scratchPad (
+ .clk_i (clk_i)
+ , .rst_i (rst_i)
+
+ , .scb_Addr_i(scb_Addr_o)
+ , .scb_Data_i(scb_Data_i)
+ , .scb_Data_o(scb_Data_o)
+ , .scb_stb_i (scb_stb_o)
+ , .scb_ce_i (scb_ce_o)
+ , .scb_rd_i (scb_rd_o)
+ , .scb_wr_i (scb_wr_o)
+ , .scb_rdy_o (scb_rdy_i)
+ );
+
+endmodule
diff --git a/verilog/rtl/Minx16/MinxFoldedBus1616.v b/verilog/rtl/Minx16/MinxFoldedBus1616.v
new file mode 100644
index 0000000..83a387a
--- /dev/null
+++ b/verilog/rtl/Minx16/MinxFoldedBus1616.v
@@ -0,0 +1,231 @@
+
+module MinxFoldedBus1616 (
+ input clk_i
+, input rst_i
+
+//Core side
+, input [A-1:0] core_Addr_i
+, input [D-1:0] core_Data_i
+, output reg [D-1:0] core_Data_o
+, input [B-1:0] core_stb_i
+, input core_rd_i
+, input core_wr_i
+, output reg core_rdy_o
+
+//Scratchpad Memory
+, output reg [A-1:0] scb_Addr_o
+, input [D-1:0] scb_Data_i
+, output reg [D-1:0] scb_Data_o
+, output reg [B-1:0] scb_stb_o
+, output reg scb_ce_o
+, output reg scb_rd_o
+, output reg scb_wr_o
+, input scb_rdy_i
+
+//Bus side with multiplexed bus
+, input [A-1:0] dbus_ADBus_i
+, output reg [D-1:0] dbus_ADBus_o
+, output reg [D-1:0] dbus_ADBus_e
+, output reg dbus_ale_o
+, output reg dbus_ale_e
+, output reg dbus_dle_o
+, output reg dbus_dle_e
+, output reg [B-1:0] dbus_stb_o
+, output reg [B-1:0] dbus_stb_e
+, output reg dbus_rd_o
+, output reg dbus_rd_e
+, output reg dbus_wr_o
+, output reg dbus_wr_e
+, input dbus_rdy_i
+
+, input dbus_req_i
+, output reg dbus_ack_o
+);
+
+ localparam SCBBASE = 16'hF800;
+
+ localparam A = 16;
+ localparam D = 16;
+ localparam B = 2;
+ localparam BUSENABLE = {D{1'b0}};
+ localparam BUSDISABLE = {D{1'b1}};
+
+ localparam STBENABLE = {B{1'b0}};
+ localparam STBDISABLE = {B{1'b1}};
+ localparam STBACTIVE = 1'b1;
+ localparam STBINACTIVE = 1'b0;
+
+ localparam ALEACTIVE = 1'b1;
+ localparam ALEINACTIVE = 1'b0;
+ localparam ALEENABLE = 1'b0;
+ localparam ALEDISABLE = 1'b1;
+
+ localparam DLEACTIVE = 1'b1;
+ localparam DLEINACTIVE = 1'b0;
+ localparam DLEENABLE = 1'b0;
+ localparam DLEDISABLE = 1'b1;
+
+ localparam RDACTIVE = 1'b0;
+ localparam RDINACTIVE = 1'b1;
+ localparam RDENABLE = 1'b0;
+ localparam RDDISABLE = 1'b1;
+
+ localparam WRACTIVE = 1'b0;
+ localparam WRINACTIVE = 1'b1;
+ localparam WRENABLE = 1'b0;
+ localparam WRDISABLE = 1'b1;
+
+ wire rdActive = core_rd_i == RDACTIVE;
+ wire wrActive = core_wr_i == WRACTIVE;
+ wire scb_cen = (core_Addr_i >= SCBBASE && core_Addr_i < SCBBASE + 2**(9+2));
+
+ reg [3:0] pstate, nstate;
+ always @ (posedge clk_i or negedge rst_i)
+ if( rst_i == 1'b0 )
+ pstate <= 0;
+ else
+ pstate <= nstate;
+
+ always @*
+ begin
+ dbus_ADBus_o = 0;
+ dbus_ADBus_e = BUSENABLE;
+ dbus_ale_o = ALEINACTIVE;
+ dbus_ale_e = ALEENABLE;
+ dbus_dle_o = DLEINACTIVE;
+ dbus_dle_e = DLEENABLE;
+ dbus_stb_o = STBINACTIVE;
+ dbus_stb_e = STBENABLE;
+ dbus_rd_o = RDINACTIVE;
+ dbus_rd_e = RDENABLE;
+ dbus_wr_o = WRINACTIVE;
+ dbus_wr_e = WRENABLE;
+ dbus_ack_o = 1'b0;
+ core_rdy_o = 1'b0;
+
+ scb_Addr_o = {A{1'b0}};
+ scb_Data_o = {D{1'b0}};
+ scb_ce_o = 1'b0;
+ scb_stb_o = {B{STBINACTIVE}};
+ scb_rd_o = RDINACTIVE;
+ scb_wr_o = WRINACTIVE;
+
+ case(pstate)
+ 4'b0000 : begin
+ core_Data_o = 0;
+ end
+ 4'b0001 : begin
+ dbus_ADBus_e = BUSDISABLE;
+ dbus_ale_e = ALEDISABLE;
+ dbus_dle_e = DLEDISABLE;
+ dbus_stb_e = STBDISABLE;
+ dbus_rd_e = RDDISABLE;
+ dbus_wr_e = WRDISABLE;
+ dbus_ack_o = 1'b1;
+ end
+ 4'b0010 : begin
+ dbus_ADBus_o = core_Addr_i;
+ dbus_stb_o = {B{STBACTIVE}};
+ dbus_ale_o = ALEINACTIVE;
+ end
+ 4'b0011 : begin
+ dbus_ADBus_o = core_Addr_i;
+ dbus_stb_o = {B{STBACTIVE}};
+ dbus_ale_o = ALEACTIVE;
+ end
+ 4'b0100 : begin
+ dbus_ADBus_o = core_Addr_i;
+ dbus_stb_o = {B{STBACTIVE}};
+ dbus_ale_o = ALEINACTIVE;
+ end
+ 4'b0101 : begin
+ dbus_ADBus_o = core_Data_i;
+ if(~wrActive)
+ dbus_ADBus_e = BUSDISABLE;
+ dbus_dle_o = DLEACTIVE;
+ dbus_stb_o = core_stb_i;
+ dbus_rd_o = RDINACTIVE;
+ dbus_wr_o = WRINACTIVE;
+ end
+ 4'b0110 : begin
+ core_Data_o = dbus_ADBus_i;
+ dbus_ADBus_o = core_Data_i;
+ if(~wrActive)
+ dbus_ADBus_e = BUSDISABLE;
+ dbus_dle_o = DLEACTIVE;
+ dbus_stb_o = core_stb_i;
+ dbus_rd_o = core_rd_i;
+ dbus_wr_o = WRINACTIVE;
+ end
+ 4'b0111 : begin
+ core_Data_o = dbus_ADBus_i;
+ dbus_ADBus_o = core_Data_i;
+ if(~wrActive)
+ dbus_ADBus_e = BUSDISABLE;
+ dbus_dle_o = DLEACTIVE;
+ dbus_stb_o = core_stb_i;
+ dbus_rd_o = core_rd_i;
+ dbus_wr_o = core_wr_i;
+ core_rdy_o = dbus_rdy_i;
+ end
+ 4'b1000 : begin
+ scb_Addr_o = core_Addr_i;
+ scb_Data_o = core_Data_i;
+ scb_ce_o = 1'b1;
+ core_Data_o = scb_Data_i;
+ scb_stb_o = core_stb_i;
+ scb_rd_o = core_rd_i;
+ scb_wr_o = core_wr_i;
+ end
+ 4'b1001 : begin
+ scb_Addr_o = core_Addr_i;
+ scb_Data_o = core_Data_i;
+ scb_ce_o = 1'b1;
+ core_Data_o = scb_Data_i;
+ scb_stb_o = core_stb_i;
+ scb_rd_o = core_rd_i;
+ scb_wr_o = core_wr_i;
+ end
+ 4'b1010 : begin
+ scb_Addr_o = core_Addr_i;
+ scb_Data_o = core_Data_i;
+ scb_ce_o = 1'b1;
+ core_Data_o = scb_Data_i;
+ scb_stb_o = core_stb_i;
+ scb_rd_o = core_rd_i;
+ scb_wr_o = core_wr_i;
+ core_rdy_o = scb_rdy_i;
+ end
+ endcase
+ end
+
+ always @*
+ begin
+ nstate = 4'b0000;
+ case(pstate)
+ 4'b0000 : begin
+ if(scb_cen & (rdActive || wrActive))
+ nstate = 4'b1000;
+ if(~scb_cen & (rdActive || wrActive))
+ nstate = 4'b0010;
+ else if( dbus_req_i )
+ nstate = 4'b0001;
+ end
+ 4'b0001 : if( dbus_req_i )
+ nstate = 4'b0001;
+ 4'b0010 : nstate = 4'b0011;
+ 4'b0011 : nstate = 4'b0100;
+ 4'b0100 : nstate = 4'b0101;
+ 4'b0101 : nstate = 4'b0110;
+ 4'b0110 : nstate = 4'b0111;
+ 4'b0111 : if( dbus_rdy_i )
+ nstate = 4'b0000;
+ else
+ nstate = 4'b0111;
+ 4'b1000 : nstate = 4'b1001;
+ 4'b1001 : nstate = 4'b1010;
+ 4'b1010 : nstate = 4'b0000;
+ endcase
+ end
+
+endmodule
diff --git a/verilog/rtl/Minx16/ParametricRegister.v b/verilog/rtl/Minx16/ParametricRegister.v
new file mode 100644
index 0000000..dd6a9c6
--- /dev/null
+++ b/verilog/rtl/Minx16/ParametricRegister.v
@@ -0,0 +1,25 @@
+
+module Register #(
+ parameter W = 8
+) (
+ input clk
+, input rst
+
+, input LD
+, input [W-1:0] D
+, output reg [W-1:0] Q
+);
+
+ initial Q = 0;
+
+ always @ (posedge clk or negedge rst)
+ begin
+ if( rst == 1'b0 )
+ Q <= 0;
+ else if (LD == 1'b1)
+ Q <= D;
+ else
+ Q <= Q;
+ end
+
+endmodule
diff --git a/verilog/rtl/Minx16/ProgramCounter.v b/verilog/rtl/Minx16/ProgramCounter.v
new file mode 100644
index 0000000..e1ebbd6
--- /dev/null
+++ b/verilog/rtl/Minx16/ProgramCounter.v
@@ -0,0 +1,28 @@
+
+module ProgramCounter #(
+ parameter W = 8
+) (
+ input clk
+, input rst
+
+, input LD
+, input INC
+, input [W-1:0] D
+, output reg [W-1:0] Q
+);
+
+ initial Q = 0;
+
+ always @ (posedge clk or negedge rst)
+ begin
+ if( rst == 1'b0 )
+ Q <= 0;
+ else if (LD == 1'b1)
+ Q <= D;
+ else if (INC == 1'b1)
+ Q <= Q + (W/8);
+ else
+ Q <= Q;
+ end
+
+endmodule
diff --git a/verilog/rtl/Minx16/RegFile.v b/verilog/rtl/Minx16/RegFile.v
new file mode 100644
index 0000000..1b00c80
--- /dev/null
+++ b/verilog/rtl/Minx16/RegFile.v
@@ -0,0 +1,49 @@
+
+module RegFile16 #(
+ parameter A = 3
+) (
+ input clk
+, input rst
+
+, input [A-1:0] ra
+, output reg [ 15:0] da
+, input [A-1:0] rb
+, output reg [ 15:0] db
+
+, input [A-1:0] rd
+, input [ 15:0] dd
+, input [ 2:0] wd
+);
+
+ localparam N = 2 ** A;
+ reg [15:0] file [N-1:0];
+
+ wire [15:0] dv = file[rd];
+ reg [15:0] df;
+ always @*
+ case(wd)
+ 3'b000 : df = dv;
+ 3'b001 : df = {dv[15:8], dd[ 7:0]};
+ 3'b010 : df = {dd[15:8], dv[ 7:0]};
+ 3'b011 : df = dd;
+ 3'b100 : df = {dv[ 7:0], dv[15:8]};
+ 3'b101 : df = {dv[ 7:0], dd[15:8]};
+ 3'b110 : df = {dd[ 7:0], dv[15:8]};
+ 3'b111 : df = {dd[ 7:0], dd[15:8]};
+ endcase
+
+ integer ii;
+ always @ (posedge clk or negedge rst)
+ if( rst == 1'b0 )
+ for(ii = 0; ii < N; ii = ii + 1)
+ file[ii] = 16'h0000;
+ else
+ file[rd] = df;
+
+ always @ (negedge clk)
+ da = file[ra];
+
+ always @ (negedge clk)
+ db = file[rb];
+
+endmodule
diff --git a/verilog/rtl/Minx16/StackPointer.v b/verilog/rtl/Minx16/StackPointer.v
new file mode 100644
index 0000000..dd3b9f1
--- /dev/null
+++ b/verilog/rtl/Minx16/StackPointer.v
@@ -0,0 +1,31 @@
+
+module StackPointer #(
+ parameter W = 8
+) (
+ input clk
+, input rst
+
+, input LD
+, input INC
+, input DEC
+, input [W-1:0] D
+, output reg [W-1:0] Q
+);
+
+ initial Q = 0;
+
+ always @ (posedge clk or negedge rst)
+ begin
+ if( rst == 1'b0 )
+ Q <= 0;
+ else if (LD == 1'b1)
+ Q <= D;
+ else if (INC == 1'b1)
+ Q <= Q + (W/8);
+ else if (DEC == 1'b1)
+ Q <= Q - (W/8);
+ else
+ Q <= Q;
+ end
+
+endmodule
diff --git a/verilog/rtl/Minx16/scb.v b/verilog/rtl/Minx16/scb.v
new file mode 100644
index 0000000..0327be0
--- /dev/null
+++ b/verilog/rtl/Minx16/scb.v
@@ -0,0 +1,76 @@
+//Design for 1024x16 or 2kb of onboard memory scratchpad
+module SCB_memory (
+ input clk_i
+, input rst_i
+
+, input [A-1:0] scb_Addr_i
+, input [D-1:0] scb_Data_i
+, output wire [D-1:0] scb_Data_o
+, input [B-1:0] scb_stb_i
+, input scb_ce_i
+, input scb_rd_i
+, input scb_wr_i
+, output wire scb_rdy_o
+);
+
+ localparam A = 11;
+ localparam D = 16;
+ localparam B = 2;
+
+ wire highSelect = scb_ce_i & scb_Addr_i[10];
+ wire lowSelect = scb_ce_i & ~scb_Addr_i[10];
+ wire oddSelect = scb_ce_i & scb_stb_i[1];
+ wire evenSelect = scb_ce_i & scb_stb_i[0];
+ wire [ 8:0] addr = scb_Addr_i[9:1];
+ wire [ 7:0] dblo = scb_Data_i[7:0];
+ wire [ 7:0] dbhi = scb_Data_i[15:8];
+
+ wire [ 7:0] dbolo, dbohi, dbelo, dbehi;
+ wire [15:0] dbol = {dbolo, dbelo};
+ wire [15:0] dboh = {dbohi, dbehi};
+
+ assign scb_rdy_o = 1'b1;
+ assign scb_Data_o = (highSelect) ? dboh :dbol;
+
+ gf180mcu_fd_ip_sram__sram512x8m8wm1 oddMemLow (
+ .CLK (clk_i)
+ , .CEN (~(oddSelect & lowSelect))
+ , .GWEN(~scb_ce_i | scb_wr_i)
+ , .WEN (8'h00)
+ , .A (addr)
+ , .D (dbhi)
+ , .Q (dbolo)
+ );
+
+ gf180mcu_fd_ip_sram__sram512x8m8wm1 oddMemHigh (
+ .CLK (clk_i)
+ , .CEN (~(oddSelect & highSelect))
+ , .GWEN(~scb_ce_i | scb_wr_i)
+ , .WEN (8'h00)
+ , .A (addr)
+ , .D (dbhi)
+ , .Q (dbohi)
+ );
+
+ gf180mcu_fd_ip_sram__sram512x8m8wm1 evenMemLow (
+ .CLK (clk_i)
+ , .CEN (~(evenSelect & lowSelect))
+ , .GWEN(~scb_ce_i | scb_wr_i)
+ , .WEN (8'h00)
+ , .A (addr)
+ , .D (dblo)
+ , .Q (dbelo)
+ );
+
+ gf180mcu_fd_ip_sram__sram512x8m8wm1 evenMemHigh(
+ .CLK (clk_i)
+ , .CEN (~(evenSelect & highSelect))
+ , .GWEN(~scb_ce_i | scb_wr_i)
+ , .WEN (8'h00)
+ , .A (addr)
+ , .D (dblo)
+ , .Q (dbehi)
+ );
+
+endmodule
+
diff --git a/verilog/rtl/Minx16/trapAddr.v b/verilog/rtl/Minx16/trapAddr.v
new file mode 100644
index 0000000..2798a97
--- /dev/null
+++ b/verilog/rtl/Minx16/trapAddr.v
@@ -0,0 +1,22 @@
+
+module trapAddr #(
+ parameter A = 16
+) (
+ input [ 2:0] trapSel
+, input [A-1:0] pc
+, output reg [A-1:0] cpc
+);
+
+ always @*
+ case(trapSel)
+ 3'b000 : cpc = pc;
+ 3'b001 : cpc = 16'h0400;
+ 3'b010 : cpc = 16'h0800;
+ 3'b011 : cpc = 16'h0c00;
+ 3'b100 : cpc = 16'h0000;
+ 3'b101 : cpc = 16'h0000;
+ 3'b110 : cpc = 16'h0000;
+ 3'b111 : cpc = pc + 2'd2;
+ endcase
+
+endmodule
diff --git a/verilog/rtl/gf180mcu_fd_ip_sram/gf180mcu_fd_ip_sram__sram512x8m8wm1.v b/verilog/rtl/gf180mcu_fd_ip_sram/gf180mcu_fd_ip_sram__sram512x8m8wm1.v
new file mode 100644
index 0000000..484732b
--- /dev/null
+++ b/verilog/rtl/gf180mcu_fd_ip_sram/gf180mcu_fd_ip_sram__sram512x8m8wm1.v
@@ -0,0 +1,465 @@
+/*
+ * $Id: $
+ * Copyright 2022 GlobalFoundries PDK Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http:www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Project: 018 5VGREEN SRAM
+ * Author: GlobalFoundries PDK Authors
+ * Data Created: 05-06-2014
+ * Revision: 0.0
+ *
+ * Description: gf180mcu_fd_ip_sram__sram512x8m8wm1 Simulation Model
+ */
+
+`timescale 1 ps / 1 ps
+
+module gf180mcu_fd_ip_sram__sram512x8m8wm1 (
+ CLK,
+ CEN,
+ GWEN,
+ WEN,
+ A,
+ D,
+ Q,
+ VDD,
+ VSS
+);
+
+input CLK;
+input CEN; //Chip Enable
+input GWEN; //Global Write Enable
+input [7:0] WEN; //Write Enable
+input [8:0] A;
+input [7:0] D;
+output [7:0] Q;
+inout VDD;
+inout VSS;
+
+reg [7:0] mem[511:0];
+reg [7:0] qo_reg;
+
+wire cen_flag;
+wire write_flag;
+wire read_flag;
+
+reg ntf_Tcyc; //notifier for clock period/low/high pulse
+reg ntf_Tckh;
+reg ntf_Tckl;
+
+reg ntf_tcs; //notifier for setup time
+reg ntf_tas;
+reg ntf_tds;
+reg ntf_tws;
+reg ntf_twis;
+
+reg ntf_tch; //notifier for hold time
+reg ntf_tah;
+reg ntf_tdh;
+reg ntf_twh;
+reg ntf_twih;
+
+wire no_st_viol; //no setup violation
+wire no_hd_viol; //no hold violation
+wire no_ck_viol; //no clock related violation
+
+reg clk_dly; //for read/write
+reg write_flag_dly; //for write invalidation
+reg read_flag_dly; //for read invalidation
+reg cen_dly;
+reg cen_fell; //detect CEN 1 -> 0 transition
+reg cen_not_rst; //detect CEN is not reset initially
+
+wire [7:0] we; //inversion of WEN
+wire [7:0] cd2;
+wire [7:0] cd4;
+wire [7:0] cd5;
+reg [7:0] cdx;
+
+reg [8:0] marked_a;
+
+integer i;
+
+assign Q = qo_reg;
+
+//---- for debugging
+wire [7:0] mem_0;
+wire [7:0] mem_1;
+wire [7:0] mem_2;
+wire [7:0] mem_3;
+assign mem_0 = mem[0];
+assign mem_1 = mem[1];
+assign mem_2 = mem[2];
+assign mem_3 = mem[3];
+
+always @(CEN) cen_dly = #100 CEN;
+always @(CEN or cen_dly) begin
+ if (!CEN & cen_dly) cen_fell = 1'b1;
+end
+
+always @(posedge CLK) begin
+ if (!CEN & !cen_fell & !cen_not_rst) cen_not_rst = 1;
+end
+
+always @(posedge cen_not_rst) begin
+ $display("-------- WARNING: CEN is not reset, memory is not operational ---------");
+ $display("-------- @Time %0t: scope = %m", $realtime, " ---------");
+end
+
+always @(posedge cen_fell) begin
+ $display("-------- MESSAGE: CEN is just reset, memory is operational ---------");
+ $display("-------- @Time %0t: scope = %m", $realtime, " ---------");
+end
+
+assign cen_flag = cen_fell & !CEN;
+assign write_flag = cen_fell & !CEN & !GWEN & !(&WEN);
+assign read_flag = cen_fell & !CEN & GWEN;
+
+reg cen_flag_dly;
+always @(cen_flag) cen_flag_dly = #100 cen_flag;
+
+specify
+ specparam Tcyc = 55600 : 55600 : 55600;
+ specparam Tckh = 25000 : 25000 : 25000;
+ specparam Tckl = 25000 : 25000 : 25000;
+
+ specparam tcs = 5000 : 5000 : 5000;
+ specparam tas = 5000 : 5000 : 5000;
+ specparam tds = 5000 : 5000 : 5000;
+ specparam tws = 5000 : 5000 : 5000;
+ specparam twis = 5000 : 5000 : 5000;
+
+ specparam tch = 10000 : 10000 : 10000;
+ specparam tah = 10000 : 10000 : 10000;
+ specparam tdh = 10000 : 10000 : 10000;
+ specparam twh = 10000 : 10000 : 10000;
+ specparam twih = 10000 : 10000 : 10000;
+
+ specparam ta = 45000 : 45000 : 45000;
+
+ specparam Tdly = 100 : 100: 100;
+
+//---- CLK period/pulse timing
+ $period (negedge CLK, Tcyc, ntf_Tcyc);
+ $width (posedge CLK, Tckh, 0, ntf_Tckh);
+ $width (negedge CLK, Tckl, 0, ntf_Tckl);
+
+//---- CEN setup/hold timing
+ $setup (negedge CEN, posedge CLK &&& cen_flag, tcs, ntf_tcs);
+ $setup (posedge CEN, posedge CLK &&& cen_flag, tcs, ntf_tcs);
+
+ $hold (posedge CLK &&& cen_flag_dly, posedge CEN, tch, ntf_tch);
+ $hold (posedge CLK &&& cen_flag, negedge CEN, tch, ntf_tch);
+
+//---- GWEN setup/hold timing
+ $setup (negedge GWEN, posedge CLK &&& cen_flag, tws, ntf_tws);
+ $setup (posedge GWEN, posedge CLK &&& cen_flag, tws, ntf_tws);
+
+ $hold (posedge CLK &&& cen_flag, posedge GWEN, twh, ntf_twh);
+ $hold (posedge CLK &&& cen_flag, negedge GWEN, twh, ntf_twh);
+
+//---- WEN[7:0] setup/hold timing
+ $setup (negedge WEN[0], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (negedge WEN[1], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (negedge WEN[2], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (negedge WEN[3], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (negedge WEN[4], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (negedge WEN[5], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (negedge WEN[6], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (negedge WEN[7], posedge CLK &&& write_flag, twis, ntf_twis);
+
+ $setup (posedge WEN[0], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (posedge WEN[1], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (posedge WEN[2], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (posedge WEN[3], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (posedge WEN[4], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (posedge WEN[5], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (posedge WEN[6], posedge CLK &&& write_flag, twis, ntf_twis);
+ $setup (posedge WEN[7], posedge CLK &&& write_flag, twis, ntf_twis);
+
+ $hold (posedge CLK &&& write_flag, posedge WEN[0], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, posedge WEN[1], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, posedge WEN[2], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, posedge WEN[3], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, posedge WEN[4], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, posedge WEN[5], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, posedge WEN[6], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, posedge WEN[7], twih, ntf_twih);
+
+ $hold (posedge CLK &&& write_flag, negedge WEN[0], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, negedge WEN[1], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, negedge WEN[2], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, negedge WEN[3], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, negedge WEN[4], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, negedge WEN[5], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, negedge WEN[6], twih, ntf_twih);
+ $hold (posedge CLK &&& write_flag, negedge WEN[7], twih, ntf_twih);
+
+//---- A[8:0] setup/hold timing
+ $setup (posedge A[0], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (posedge A[1], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (posedge A[2], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (posedge A[3], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (posedge A[4], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (posedge A[5], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (posedge A[6], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (posedge A[7], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (posedge A[8], posedge CLK &&& cen_flag, tas, ntf_tas);
+
+ $setup (negedge A[0], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (negedge A[1], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (negedge A[2], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (negedge A[3], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (negedge A[4], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (negedge A[5], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (negedge A[6], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (negedge A[7], posedge CLK &&& cen_flag, tas, ntf_tas);
+ $setup (negedge A[8], posedge CLK &&& cen_flag, tas, ntf_tas);
+
+ $hold (posedge CLK &&& cen_flag, negedge A[0], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, negedge A[1], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, negedge A[2], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, negedge A[3], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, negedge A[4], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, negedge A[5], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, negedge A[6], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, negedge A[7], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, negedge A[8], tah, ntf_tah);
+
+ $hold (posedge CLK &&& cen_flag, posedge A[0], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, posedge A[1], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, posedge A[2], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, posedge A[3], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, posedge A[4], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, posedge A[5], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, posedge A[6], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, posedge A[7], tah, ntf_tah);
+ $hold (posedge CLK &&& cen_flag, posedge A[8], tah, ntf_tah);
+
+//---- D[7:0] setup/hold timing
+ $setup (posedge D[0], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (posedge D[1], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (posedge D[2], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (posedge D[3], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (posedge D[4], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (posedge D[5], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (posedge D[6], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (posedge D[7], posedge CLK &&& write_flag, tds, ntf_tds);
+
+ $setup (negedge D[0], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (negedge D[1], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (negedge D[2], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (negedge D[3], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (negedge D[4], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (negedge D[5], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (negedge D[6], posedge CLK &&& write_flag, tds, ntf_tds);
+ $setup (negedge D[7], posedge CLK &&& write_flag, tds, ntf_tds);
+
+ $hold (posedge CLK &&& write_flag, negedge D[0], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, negedge D[1], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, negedge D[2], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, negedge D[3], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, negedge D[4], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, negedge D[5], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, negedge D[6], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, negedge D[7], tdh, ntf_tdh);
+
+ $hold (posedge CLK &&& write_flag, posedge D[0], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, posedge D[1], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, posedge D[2], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, posedge D[3], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, posedge D[4], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, posedge D[5], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, posedge D[6], tdh, ntf_tdh);
+ $hold (posedge CLK &&& write_flag, posedge D[7], tdh, ntf_tdh);
+
+//---- Output delay
+// rise transition: 0->1, z->1, Ta
+// fall transition: 1->0, 1->z, Ta
+// turn-off transition: 0->z, 1->z, Tcqx
+//if (!CEN & GWEN) (posedge CLK => (Q : 8'bx)) = (Ta, Ta, Tcqx);
+if ((CEN == 1'b0) && (GWEN == 1'b1)) (posedge CLK => (Q[0] : 1'bx)) = (ta, ta);
+if ((CEN == 1'b0) && (GWEN == 1'b1)) (posedge CLK => (Q[1] : 1'bx)) = (ta, ta);
+if ((CEN == 1'b0) && (GWEN == 1'b1)) (posedge CLK => (Q[2] : 1'bx)) = (ta, ta);
+if ((CEN == 1'b0) && (GWEN == 1'b1)) (posedge CLK => (Q[3] : 1'bx)) = (ta, ta);
+if ((CEN == 1'b0) && (GWEN == 1'b1)) (posedge CLK => (Q[4] : 1'bx)) = (ta, ta);
+if ((CEN == 1'b0) && (GWEN == 1'b1)) (posedge CLK => (Q[5] : 1'bx)) = (ta, ta);
+if ((CEN == 1'b0) && (GWEN == 1'b1)) (posedge CLK => (Q[6] : 1'bx)) = (ta, ta);
+if ((CEN == 1'b0) && (GWEN == 1'b1)) (posedge CLK => (Q[7] : 1'bx)) = (ta, ta);
+endspecify
+
+assign no_st_viol = ~(|{ntf_tcs, ntf_tas, ntf_tds, ntf_tws, ntf_twis});
+assign no_hd_viol = ~(|{ntf_tch, ntf_tah, ntf_tdh, ntf_twh, ntf_twih});
+assign no_ck_viol = ~(|{ntf_Tcyc, ntf_Tckh, ntf_Tckl});
+
+always @(CLK) clk_dly = #Tdly CLK;
+always @(CLK) write_flag_dly = #200 write_flag;
+always @(CLK) read_flag_dly = #200 read_flag;
+
+always @(posedge CLK) marked_a = A;
+
+assign we = ~WEN;
+assign cd2 = mem[A] & WEN; //set write bits to 0, others unchanged
+assign cd4 = D & we; //set write bits to 0/1, others = 0
+assign cd5 = cd2 | cd4; //memory content after write
+
+always @(posedge CLK) cdx = {8{1'bx}} & we; //latch cdx
+
+always @(posedge clk_dly) begin
+ if (write_flag) begin //write
+ if (no_st_viol) begin //write, no viol
+ mem[A] = cd5;
+ end
+ else begin //write, with viol
+ mem[A] = mem[A] ^ cdx; //1^x = x
+ qo_reg = qo_reg ^ cdx;
+ end
+ end //write
+ else if (read_flag) begin //read
+ if (no_st_viol) begin //read, no viol
+ qo_reg = mem[marked_a];
+ end
+ else begin //read, with viol
+ qo_reg = 8'bx;
+ end
+ end //read
+end
+
+always @(negedge clk_dly) begin //invalidate write/read when hold/clk viol
+ if (no_hd_viol == 0 | no_ck_viol == 0) begin
+ if (write_flag_dly) begin
+ if (ntf_twh) begin
+ mem[marked_a] = mem[marked_a] ^ 8'bx; //GWEN can't be used to generate cdx
+ qo_reg = qo_reg ^ 8'bx;
+ end
+ else begin
+ mem[marked_a] = mem[marked_a] ^ cdx;
+ qo_reg = qo_reg ^ cdx;
+ end
+ end
+ else if (read_flag_dly) begin
+ qo_reg = 8'bx;
+ end
+
+ #100;
+ ntf_tch = 0;
+ ntf_tah = 0;
+ ntf_tdh = 0;
+ ntf_twh = 0;
+ ntf_twih = 0;
+
+ ntf_Tcyc = 0;
+ ntf_Tckh = 0;
+ ntf_Tckl = 0;
+ end
+ else begin
+ #100;
+ ntf_tch = 0;
+ ntf_tah = 0;
+ ntf_tdh = 0;
+ ntf_twh = 0;
+ ntf_twih = 0;
+
+ ntf_Tcyc = 0;
+ ntf_Tckh = 0;
+ ntf_Tckl = 0;
+ end
+end
+
+always @(posedge ntf_tcs or posedge ntf_tas or posedge ntf_tds or
+ posedge ntf_tws or posedge ntf_twis or
+ posedge ntf_tch or posedge ntf_tah or posedge ntf_tdh or
+ posedge ntf_twh or posedge ntf_twih or
+ posedge ntf_Tcyc or posedge ntf_Tckh or posedge ntf_Tckl) begin
+ if (cen_fell) begin
+ #Tdly;
+ if (ntf_tcs) $display("---- ERROR: CEN setup violation! ----");
+ if (ntf_tas) $display("---- ERROR: A setup violation! ----");
+ if (ntf_tds) $display("---- ERROR: D setup violation! ----");
+ if (ntf_tws) $display("---- ERROR: GWEN setup violation! ----");
+ if (ntf_twis) $display("---- ERROR: WEN setup violation! ----");
+
+ if (ntf_tch) $display("---- ERROR: CEN hold violation! ----");
+ if (ntf_tah) $display("---- ERROR: A hold violation! ----");
+ if (ntf_tdh) $display("---- ERROR: D hold violation! ----");
+ if (ntf_twh) $display("---- ERROR: GWEN hold violation! ----");
+ if (ntf_twih) $display("---- ERROR: WEN hold violation! ----");
+
+ if (ntf_Tcyc) $display("---- ERROR: CLK period violation! ----");
+ if (ntf_Tckh) $display("---- ERROR: CLK pulse width high violation! ----");
+ if (ntf_Tckl) $display("---- ERROR: CLK pulse width low violation! ----");
+ end
+end
+
+always @(posedge cen_fell) begin //reset fasle notifiers
+ ntf_tcs = 0; //after CEN reset (CEN from 1 to 0)
+ ntf_tas = 0;
+ ntf_tds = 0;
+ ntf_tws = 0;
+ ntf_twis = 0;
+
+ ntf_tch = 0;
+ ntf_tah = 0;
+ ntf_tdh = 0;
+ ntf_twh = 0;
+ ntf_twih = 0;
+end
+
+always @(negedge clk_dly) begin //reset setup/hold notifiers
+ #100;
+ ntf_tcs = 0;
+ ntf_tas = 0;
+ ntf_tds = 0;
+ ntf_tws = 0;
+ ntf_twis = 0;
+
+ ntf_tch = 0;
+ ntf_tah = 0;
+ ntf_tdh = 0;
+ ntf_twh = 0;
+ ntf_twih = 0;
+end
+
+initial begin //initialization
+ ntf_Tcyc = 0;
+ ntf_Tckh = 0;
+ ntf_Tckl = 0;
+
+ ntf_tcs = 0;
+ ntf_tas = 0;
+ ntf_tds = 0;
+ ntf_tws = 0;
+ ntf_twis = 0;
+
+ ntf_tch = 0;
+ ntf_tah = 0;
+ ntf_tdh = 0;
+ ntf_twh = 0;
+ ntf_twih = 0;
+
+ marked_a = 9'd0;
+
+ qo_reg = 8'd0;
+ clk_dly = 0;
+ write_flag_dly = 0;
+ read_flag_dly = 0;
+ cen_dly = 0;
+ cen_fell = 0;
+ cen_not_rst = 0;
+
+ for(i=0; i<512; i=i+1) begin
+ mem[i] = 8'd0;
+ end
+end
+
+endmodule
diff --git a/verilog/rtl/user_proj_example.v b/verilog/rtl/user_proj_example.v
index 26081e9..04421fe 100644
--- a/verilog/rtl/user_proj_example.v
+++ b/verilog/rtl/user_proj_example.v
@@ -18,20 +18,7 @@
*-------------------------------------------------------------
*
* user_proj_example
- *
- * This is an example of a (trivially simple) user project,
- * showing how the user project can connect to the logic
- * analyzer, the wishbone bus, and the I/O pads.
- *
- * This project generates an integer count, which is output
- * on the user area GPIO pads (digital output only). The
- * wishbone connection allows the project to be controlled
- * (start and stop) from the management SoC program.
- *
- * See the testbenches in directory "mprj_counter" for the
- * example programs that drive this user project. The three
- * testbenches are "io_ports", "la_test1", and "la_test2".
- *
+ *
*-------------------------------------------------------------
*/
@@ -44,17 +31,17 @@
`endif
// Wishbone Slave ports (WB MI A)
- input wb_clk_i,
- input wb_rst_i,
- input wbs_stb_i,
- input wbs_cyc_i,
- input wbs_we_i,
- input [3:0] wbs_sel_i,
- input [31:0] wbs_dat_i,
- input [31:0] wbs_adr_i,
- output wbs_ack_o,
+ input wb_clk_i,
+ input wb_rst_i,
+ input wbs_stb_i,
+ input wbs_cyc_i,
+ input wbs_we_i,
+ input [ 3:0] wbs_sel_i,
+ input [31:0] wbs_dat_i,
+ input [31:0] wbs_adr_i,
+ output wbs_ack_o,
output [31:0] wbs_dat_o,
-
+
// Logic Analyzer Signals
input [127:0] la_data_in,
output [127:0] la_data_out,
@@ -68,98 +55,74 @@
// IRQ
output [2:0] irq
);
- wire clk;
- wire rst;
-
- wire [`MPRJ_IO_PADS-1:0] io_in;
- wire [`MPRJ_IO_PADS-1:0] io_out;
- wire [`MPRJ_IO_PADS-1:0] io_oeb;
-
- wire [31:0] rdata;
- wire [31:0] wdata;
- wire [BITS-1:0] count;
-
- wire valid;
- wire [3:0] wstrb;
- wire [31:0] la_write;
-
- // WB MI A
- assign valid = wbs_cyc_i && wbs_stb_i;
- assign wstrb = wbs_sel_i & {4{wbs_we_i}};
- assign wbs_dat_o = rdata;
- assign wdata = wbs_dat_i;
-
- // IO
- assign io_out = count;
- assign io_oeb = {(`MPRJ_IO_PADS-1){rst}};
-
- // IRQ
- assign irq = 3'b000; // Unused
-
- // LA
- assign la_data_out = {{(127-BITS){1'b0}}, count};
- // Assuming LA probes [63:32] are for controlling the count register
- assign la_write = ~la_oenb[63:32] & ~{BITS{valid}};
- // Assuming LA probes [65:64] are for controlling the count clk & reset
- assign clk = (~la_oenb[64]) ? la_data_in[64]: wb_clk_i;
- assign rst = (~la_oenb[65]) ? la_data_in[65]: wb_rst_i;
-
- counter #(
- .BITS(BITS)
- ) counter(
- .clk(clk),
- .reset(rst),
- .ready(wbs_ack_o),
- .valid(valid),
- .rdata(rdata),
- .wdata(wbs_dat_i),
- .wstrb(wstrb),
- .la_write(la_write),
- .la_input(la_data_in[63:32]),
- .count(count)
- );
-
+
+ wire [`MPRJ_IO_PADS-1:0] io_in;
+ wire [`MPRJ_IO_PADS-1:0] io_out;
+ wire [`MPRJ_IO_PADS-1:0] io_oeb;
+
+ wire [1:0] mode = io_in[37:36];
+
+
+
+ Minx16Top cpu16 (
+ .clk_i (io_in [33])
+ , .rst_i (io_in [32])
+
+ , .dbus_ADBus_i(io_in [31:16])
+ , .dbus_ADBus_o(io_out[31:16])
+ , .dbus_ADBus_e(io_oeb[31:16])
+ , .dbus_ale_o (io_out[15])
+ , .dbus_ale_e (io_oeb[15])
+ , .dbus_dle_o (io_out[14])
+ , .dbus_dle_e (io_oeb[14])
+ , .dbus_stb_o (io_out[13:12])
+ , .dbus_stb_e (io_oeb[13:12])
+ , .dbus_rd_o (io_out[11])
+ , .dbus_rd_e (io_oeb[11])
+ , .dbus_wr_o (io_out[10])
+ , .dbus_wr_e (io_oeb[10])
+ , .dbus_rdy_i (io_in [9])
+
+ , .dbus_req_i (io_in [8])
+ , .dbus_ack_o (io_out[7])
+
+ , .intr_i (io_in [6])
+ , .inta_o (io_out[5])
+ , .nmir_i (io_in [34])
+ , .nmia_o (io_out[35])
+ );
+
endmodule
-module counter #(
- parameter BITS = 32
-)(
- input clk,
- input reset,
- input valid,
- input [3:0] wstrb,
- input [BITS-1:0] wdata,
- input [BITS-1:0] la_write,
- input [BITS-1:0] la_input,
- output ready,
- output [BITS-1:0] rdata,
- output [BITS-1:0] count
+(* blackbox *)
+module Minx16Top (
+ input clk_i
+, input rst_i
+
+, input [15:0] dbus_ADBus_i
+, output wire [15:0] dbus_ADBus_o
+, output wire [15:0] dbus_ADBus_e
+, output wire dbus_ale_o
+, output wire dbus_ale_e
+, output wire dbus_dle_o
+, output wire dbus_dle_e
+, output wire [ 1:0] dbus_stb_o
+, output wire [ 1:0] dbus_stb_e
+, output wire dbus_rd_o
+, output wire dbus_rd_e
+, output wire dbus_wr_o
+, output wire dbus_wr_e
+, input dbus_rdy_i
+
+, input dbus_req_i
+, output wire dbus_ack_o
+
+, input intr_i
+, output wire inta_o
+, input nmir_i
+, output wire nmia_o
);
- reg ready;
- reg [BITS-1:0] count;
- reg [BITS-1:0] rdata;
-
- always @(posedge clk) begin
- if (reset) begin
- count <= 0;
- ready <= 0;
- end else begin
- ready <= 1'b0;
- if (~|la_write) begin
- count <= count + 1;
- end
- if (valid && !ready) begin
- ready <= 1'b1;
- rdata <= count;
- if (wstrb[0]) count[7:0] <= wdata[7:0];
- if (wstrb[1]) count[15:8] <= wdata[15:8];
- if (wstrb[2]) count[23:16] <= wdata[23:16];
- if (wstrb[3]) count[31:24] <= wdata[31:24];
- end else if (|la_write) begin
- count <= la_write & la_input;
- end
- end
- end
endmodule
+
`default_nettype wire