Merge branch 'main' of github.com:rolfmobile99/tiny_user_project into main
diff --git a/info.yaml b/info.yaml
index d15b271..9f4bf39 100644
--- a/info.yaml
+++ b/info.yaml
@@ -3,8 +3,9 @@
 project:
   wokwi_id:    0        # If using wokwi, set this to your project's ID
   source_files:        # If using an HDL, set wokwi_id as 0 and uncomment and list your source files here
+    - verilog/rtl/regfile_top.v
     - verilog/rtl/xnor1.v
-    - verilog/rtl/top.v
+    - verilog/rtl/regfile16x4.v
   top_module:  "rolfmobile99_top"      # put the name of your top module here, make it unique by prepending your github username
 
 # As everyone will have access to all designs, try to make it easy for someone new to your design to know what
@@ -16,8 +17,8 @@
 documentation: 
   author:       "Rolf Widenfelt"      # Your name
   discord:      ""      # Your discord handle - make sure to include the # part as well
-  title:        "Collection of GF180 standard cells"      # Project title
-  description:  ""      # Short description of what your project does
+  title:        "16 x 4-bit dual port register file + XNOR"      # Project title
+  description:  "A dual port register file + XNOR test gate"      # Short description of what your project does
   how_it_works: ""      # Longer description of how the project works
   how_to_test:  ""      # Instructions on how someone could test your project, include things like what buttons do what and how to set the clock if needed
   external_hw:  ""      # Describe any external hardware needed
@@ -28,19 +29,30 @@
   inputs:               # a description of what the inputs do
     - clock
     - reset
-    - xnor_a
+    - xnor_a        # inputs for XNOR gate
     - xnor_b
-    - none
-    - none
-    - none
-    - none
+    - en1           # inputs for regfile
+    - en2
+    - wrEn
+    - rdAddr1_3
+    - rdAddr1_2
+    - rdAddr1_1
+    - rdAddr1_0
+    - rdAddr2_3
+    - rdAddr2_2
+    - rdAddr2_1
+    - rdAddr2_0
+    - dataIn_3
+    - dataIn_2
+    - dataIn_1
+    - dataIn_0
   outputs:
-    - xnor_y         # output of XNOR gate
-    - none
-    - none
-    - none
-    - none
-    - none
-    - none
-    - none
-
+    - xnor_y         # output for XNOR gate
+    - dataBusA_3     # outputs for regfile
+    - dataBusA_2
+    - dataBusA_1
+    - dataBusA_0
+    - dataBusB_3
+    - dataBusB_2
+    - dataBusB_1
+    - dataBusB_0
diff --git a/verilog/rtl/regfile16x4.v b/verilog/rtl/regfile16x4.v
new file mode 100644
index 0000000..1a545f2
--- /dev/null
+++ b/verilog/rtl/regfile16x4.v
@@ -0,0 +1,91 @@
+//
+// regfile16x4.sv - 16 x 4-bit register file, single and dual port
+//
+// note: see below for dual read port version
+//
+// rev history:
+//	12/4/2022 - based on LM3000 regfile.v
+//
+// inputs:
+//	rdAddr - read address
+//	rdOutEn - enable read register to appear on 'data' lines
+//	wrAddr - write address
+//	wrEn - write 'data' lines to selected (write) register
+//	clk - this actually does the write
+//	dataIn - data in (for register write)
+//
+// outputs:
+//	dataOut - data out for register read (tristate)
+//
+module regfile(rdAddr, rdOutEn, wrAddr, wrEn, clk, dataIn, dataOut);
+
+  input [3:0] rdAddr;   // 4-bit addressing
+  input rdOutEn;
+  input [3:0] wrAddr;
+  input wrEn;
+  input clk;
+  input tri [3:0] dataIn;	// tristate
+  output tri [3:0] dataOut;	// tristate
+  
+  reg [3:0] memory[0:15];	// we define 16 4-bit registers
+
+  assign dataOut = (rdOutEn)? memory[rdAddr]: 4'bzzzz;
+
+  always @(posedge clk) begin
+    if (wrEn) begin
+      // this writes to location wrAddr
+      memory[wrAddr] <= dataIn;
+    end
+  end
+
+endmodule
+
+
+//
+// regfile16x4_dual.sv - 16 x 4-bit register file
+//
+// rev history:
+//	12/4/2022 - based on LM3000 regfile.v
+//
+// inputs:
+//	rdAddr - read address
+//	rdOutEn - enable read register to appear on 'data' lines
+//	wrAddr - write address
+//	wrEn - write 'data' lines to selected (write) register
+//	clk - this actually does the write
+//	dataIn - data in (for register write)
+//
+// outputs:
+//	dataOut - data out for register read (tristate)
+//
+
+module regfile16x4_dual(rdAddr1, rdOutEn1, rdAddr2, rdOutEn2, wrAddr, wrEn, clk, dataIn, dataOut1, dataOut2);
+
+  input [3:0] rdAddr1;   // 4-bit addressing
+  input rdOutEn1;
+  input [3:0] rdAddr2;
+  input rdOutEn2;
+  input [3:0] wrAddr;
+  input wrEn;
+  input clk;
+  input [3:0] dataIn;
+  output tri [3:0] dataOut1;	// tristate
+  output tri [3:0] dataOut2;	// tristate
+  
+  reg [3:0] memory[0:15];	// we define 16 4-bit registers
+
+  // note: these are dual read ports - does this synthesize??
+  assign dataOut1 = (rdOutEn1)? memory[rdAddr1]: 4'bzzzz;
+
+  assign dataOut2 = (rdOutEn2)? memory[rdAddr2]: 4'bzzzz;
+
+  always @(posedge clk) begin
+    if (wrEn) begin
+      // this writes to location wrAddr
+      //$display("** %g regfile: writing [%b] = %b (0x%0x)", $time, wrAddr, dataIn, dataIn);
+      memory[wrAddr] <= dataIn;
+    end
+  end
+
+  
+endmodule
diff --git a/verilog/rtl/regfile_top.v b/verilog/rtl/regfile_top.v
new file mode 100644
index 0000000..d3be451
--- /dev/null
+++ b/verilog/rtl/regfile_top.v
@@ -0,0 +1,88 @@
+`default_nettype none
+
+//
+// top level module
+//
+
+module rolfmobile99_top(
+  input [18:0] io_in,  // 19 inputs
+  output [8:0] io_out  // 9 outputs
+);
+
+  // note: these assigments should match inputs/outputs declared in info.yaml!
+  wire clk = io_in[0];
+  wire reset = io_in[1];
+  wire xnor_a = io_in[2];
+  wire xnor_b = io_in[3];
+
+  // regfile inputs
+  wire en1 = io_in[4];
+  wire en2 = io_in[5];
+  wire wrEn = io_in[6];
+  wire [3:0] rdAddr1 = io_in[10:7];
+  wire [3:0] rdAddr2 = io_in[14:11];
+  wire [3:0] dataIn = io_in[18:15];
+
+  
+  // XNOR output
+  assign io_out[0] = xnor_y;
+  
+  // regfile outputs
+  assign io_out[4:1] = dataBusA;
+  assign io_out[8:5] = dataBusB;
+
+
+  // io_out[6:0] = ... ; // notused
+
+  wire xnor_y;
+
+  // connect modules
+
+  // first, just an XNOR gate
+  xnor1 xnor1(.a(xnor_a),
+             .b(xnor_b),
+             .y(xnor_y));
+
+  // second, a 16x4 bit register file (see below!)
+
+  // needs the following:
+  // inputs: (4+15)
+  // - clk 1
+  // - reset 1
+  // - xnor_a 1
+  // - xnor_b 1
+  //
+  // - en1 1
+  // - en2 1
+  // - wrEn 1
+  // - rdAddr1 4
+  // - rdAddr2 4
+  // - wrAddr 4  (can combine with rdAddr1)
+  // - dataIn 4
+  //
+  // outputs (1+8):
+  // - xnor_y 1
+  //
+  // - dataBusA 4
+  // - dataBusB 4
+
+  wire [3:0] dataBusA;
+  wire [3:0] dataBusB;
+
+  wire [3:0] wrAddr;
+
+  assign wrAddr[3:0] = rdAddr1[3:0];    // combine with rdAddr1 to save input pins
+
+
+  regfile16x4_dual regfile(.rdAddr1(rdAddr1),
+                  .rdOutEn1(en1),
+                  .rdAddr2(rdAddr2),
+                  .rdOutEn2(en2),
+                  .wrAddr(wrAddr),
+                  .clk(clk),
+                  .wrEn(wrEn),
+                  .dataIn(dataIn),
+                  .dataOut1(dataBusA),
+                  .dataOut2(dataBusB) );
+
+endmodule