Added SPM RTL
diff --git a/verilog/rtl/user_project/multifsm.v b/verilog/rtl/user_project/multifsm.v
new file mode 100644
index 0000000..c7d977b
--- /dev/null
+++ b/verilog/rtl/user_project/multifsm.v
@@ -0,0 +1,46 @@
+/*******************************************************************
+*
+* Module: multifsm.v
+* Project: Serial_Parallel_Multiplier
+* Author: @manarabdelatty manarabdelatty@aucegypt.edu
+* Description: Finite state machine to managae the stages of the multiplier and generate control signals.
+*
+* Change history:
+**********************************************************************/
+
+`timescale 1ns/1ns
+
+module multifsm(clk, rst, proddone, start, done, ld, shift);
+
+ input clk;
+ input rst;
+ input start;
+ input proddone;
+ output done;
+ output ld;
+ output shift;
+
+ parameter [1:0] IDLE=2'b00, MUL=2'b01 , DONE= 2'b10;
+ reg [1:0] state , newstate;
+
+ always @* begin
+ newstate = IDLE;
+ case (state)
+ IDLE: if (start) newstate= MUL; else newstate= IDLE;
+ MUL: if (start & proddone) newstate = DONE; else if (start) newstate = MUL; else newstate = IDLE;
+ DONE: if(start) newstate= DONE ; else newstate= IDLE;
+ endcase
+
+ end
+
+ always @( posedge clk or posedge rst)
+ if (rst)
+ state <= IDLE;
+ else state <= newstate;
+
+ assign done = (state == DONE);
+ assign ld = (state == IDLE);
+ assign shift = (state== MUL) && !proddone;
+
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/user_project/shift_right.v b/verilog/rtl/user_project/shift_right.v
new file mode 100644
index 0000000..7375f1d
--- /dev/null
+++ b/verilog/rtl/user_project/shift_right.v
@@ -0,0 +1,39 @@
+/*******************************************************************
+*
+* Module: shift_right.v
+* Project: Serial_Parallel_Multiplier
+* Author: @manarabdelatty manarabdelatty@aucegypt.edu
+* Description: Shift right register. Parallel Input and serial output.
+*
+* Change history:
+*
+**********************************************************************/
+`timescale 1ns/1ns
+
+module shift_right(x,clk, rst,ld, shift, out);
+
+ input clk;
+ input rst;
+ input ld;
+ input shift;
+ input [63:0]x;
+ output reg out;
+ reg [63:0] shiftreg;
+
+
+ always @(posedge clk or posedge rst) begin
+ if (rst) begin
+ shiftreg <= 0;
+ out <= 1'b0;
+ end
+ else if (ld) begin
+ shiftreg <= x;
+ out <= 1'b0;
+ end
+ else if(shift) begin
+ out <= shiftreg[0];
+ shiftreg <= {1'b0,shiftreg[63:1]}; ;
+ end
+ end
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/user_project/spm.v b/verilog/rtl/user_project/spm.v
new file mode 100644
index 0000000..f5b5053
--- /dev/null
+++ b/verilog/rtl/user_project/spm.v
@@ -0,0 +1,95 @@
+// Copyright 2020 Efabless Corporation
+//
+// 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.
+
+module spm(clk, rst, x, y, ld, p);
+ parameter size = 32;
+ input clk, rst;
+ input y;
+ input[size-1:0] x;
+ input ld;
+ output p;
+
+ wire[size-1:1] pp;
+ wire[size-1:0] xy;
+
+ genvar i;
+
+ CSADD csa0 (.clk(clk), .rst(rst), .x(x[0]&y), .y(pp[1]), .ld(ld), .sum(p));
+ generate for(i=1; i<size-1; i=i+1) begin
+ CSADD csa (.clk(clk), .rst(rst), .x(x[i]&y), .y(pp[i+1]), .ld(ld), .sum(pp[i]));
+ end endgenerate
+ TCMP tcmp (.clk(clk), .rst(rst), .a(x[size-1]&y), .ld(ld), .s(pp[size-1]));
+
+endmodule
+
+module TCMP(clk, rst, a, ld, s);
+ input clk, rst;
+ input a;
+ input ld;
+ output reg s;
+
+ reg z;
+
+ always @(posedge clk or posedge rst) begin
+ if (rst) begin
+ //Reset logic goes here.
+ s <= 1'b0;
+ z <= 1'b0;
+ end
+ else if (ld) begin // idle state reset before each input word
+ s <= 1'b0;
+ z <= 1'b0;
+ end
+ else begin
+ //Sequential logic goes here.
+ z <= a | z;
+ s <= a ^ z;
+ end
+ end
+endmodule
+
+module CSADD(clk, rst, x, y, ld, sum);
+ input clk, rst;
+ input x, y;
+ input ld;
+ output reg sum;
+
+ reg sc;
+
+ // Half Adders logic
+ wire hsum1, hco1;
+ assign hsum1 = y ^ sc;
+ assign hco1 = y & sc;
+
+ wire hsum2, hco2;
+ assign hsum2 = x ^ hsum1;
+ assign hco2 = x & hsum1;
+
+ always @(posedge clk or posedge rst) begin
+ if (rst) begin
+ //Reset logic goes here.
+ sum <= 1'b0;
+ sc <= 1'b0;
+ end
+ else if (ld) begin
+ sum <= 1'b0;
+ sc <= 1'b0;
+ end
+ else begin
+ //Sequential logic goes here.
+ sum <= hsum2;
+ sc <= hco1 ^ hco2;
+ end
+ end
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/user_project/spm_top.v b/verilog/rtl/user_project/spm_top.v
new file mode 100644
index 0000000..5e53873
--- /dev/null
+++ b/verilog/rtl/user_project/spm_top.v
@@ -0,0 +1,57 @@
+/*******************************************************************
+*
+* Module: top.v
+* Project: Serial_Parallel_Multiplier
+* Author: @manarabdelatty manarabdelatty@aucegypt.edu
+* Description: Top module
+*
+* Change history:
+*
+**********************************************************************/
+`timescale 1ns/1ns
+
+module spm_top(mc, mp ,clk, rst, prod, start, done);
+
+ input clk;
+ input rst;
+ input [31:0] mc;
+ input [31:0] mp;
+ input start;
+ output reg [63:0] prod;
+ output done;
+ wire ybit;
+ wire prodbit;
+ wire proddone;
+ wire ld;
+ wire shift;
+ reg [6:0] count; // count number of clk cycles
+
+
+
+ shift_right shifter ( .x({{32 {mp[31]}},mp[31:0]}) , .clk(clk) , .rst(rst) , .ld(ld), .shift(shift), .out(ybit));
+ spm multiplier ( .x(mc[31:0]) ,.y(ybit) , .clk(clk) , .rst(rst) , .ld(ld) , .p(prodbit) );
+ multifsm fsm ( .clk(clk) , .rst(rst) , .proddone(proddone), .start(start), .done(done), .ld(ld), .shift(shift));
+
+ always @(posedge clk or posedge rst)
+ if (rst) begin
+ prod <= 0;
+ count <=0;
+ end
+ else begin
+ if (shift) begin // Multiply state
+ prod <= {prodbit, prod[63:1]};
+ count <= count+1;
+ end
+ else if (ld) begin // idle state
+ count <= 0;
+ prod <= 0;
+ end
+ else begin // done state
+ count <= count;
+ prod <= prod;
+ end
+ end
+
+ assign proddone = (count==66);
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/user_project/user_proj_top.v b/verilog/rtl/user_project/user_proj_top.v
new file mode 100644
index 0000000..cd71232
--- /dev/null
+++ b/verilog/rtl/user_project/user_proj_top.v
@@ -0,0 +1,24 @@
+module user_proj_top (mc, mp ,clk, rst, prod, start, done, tie);
+
+ input clk;
+ input rst;
+ input [31:0] mc;
+ input [31:0] mp;
+ input start;
+ output [63:0] prod;
+ output done;
+ output [169:0] tie;
+
+ spm_top spm_top (
+ .clk(clk),
+ .rst(rst),
+ .mc(mc),
+ .mp(mp),
+ .start(start),
+ .prod(prod),
+ .done(done)
+ );
+
+ assign tie = 170'd0;
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/user_project/user_project_wrapper.v b/verilog/rtl/user_project/user_project_wrapper.v
new file mode 100644
index 0000000..0fb61a0
--- /dev/null
+++ b/verilog/rtl/user_project/user_project_wrapper.v
@@ -0,0 +1,118 @@
+// SPDX-FileCopyrightText: 2020 Efabless Corporation
+//
+// 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.
+// SPDX-License-Identifier: Apache-2.0
+
+`default_nettype none
+/*
+ *-------------------------------------------------------------
+ *
+ * user_project_wrapper
+ *
+ * This wrapper enumerates all of the pins available to the
+ * user for the user project.
+ *
+ * An example user project is provided in this wrapper. The
+ * example should be removed and replaced with the actual
+ * user project.
+ *
+ *-------------------------------------------------------------
+ */
+
+`define MPRJ_IO_PADS 38
+
+module user_project_wrapper (
+`ifdef USE_POWER_PINS
+ inout vdda1, // User area 1 3.3V supply
+ inout vdda2, // User area 2 3.3V supply
+ inout vssa1, // User area 1 analog ground
+ inout vssa2, // User area 2 analog ground
+ inout vccd1, // User area 1 1.8V supply
+ inout vccd2, // User area 2 1.8v supply
+ inout vssd1, // User area 1 digital ground
+ inout vssd2, // User area 2 digital ground
+`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 reg wbs_ack_o,
+ output [31:0] wbs_dat_o,
+
+ // Logic Analyzer Signals
+ input [127:0] la_data_in,
+ output [127:0] la_data_out,
+ input [127:0] la_oen,
+
+ // IOs
+ input [`MPRJ_IO_PADS-1:0] io_in,
+ output [`MPRJ_IO_PADS-1:0] io_out,
+ output [`MPRJ_IO_PADS-1:0] io_oeb,
+
+ // Analog (direct connection to GPIO pad---use with caution)
+ // Note that analog I/O is not available on the 7 lowest-numbered
+ // GPIO pads, and so the analog_io indexing is offset from the
+ // GPIO indexing by 7.
+ inout [`MPRJ_IO_PADS-8:0] analog_io,
+
+ // Independent clock (on independent integer divider)
+ input user_clock2
+);
+
+ /*--------------------------------------*/
+ /* User project is instantiated here */
+ /*--------------------------------------*/
+
+ user_proj_top user_proj_top (
+ `ifdef USE_POWER_PINS
+ .vdda1(vdda1), // User area 1 3.3V power
+ .vdda2(vdda2), // User area 2 3.3V power
+ .vssa1(vssa1), // User area 1 analog ground
+ .vssa2(vssa2), // User area 2 analog ground
+ .vccd1(vccd1), // User area 1 1.8V power
+ .vccd2(vccd2), // User area 2 1.8V power
+ .vssd1(vssd1), // User area 1 digital ground
+ .vssd2(vssd2), // User area 2 digital ground
+ `endif
+
+ // MGMT core clock and reset
+
+ .clk(wb_clk_i),
+ .rst(wb_rst_i),
+
+ // Logic Analyzer
+
+ .mc (la_data_in[31:0]),
+ .mp (la_data_in[63:32]),
+ .start (la_data_in[64]),
+ .done (la_data_out[0]),
+ .prod (la_data_out[127:64]),
+ .tie ({io_oeb[`MPRJ_IO_PADS-1:5], io_oeb[3:0], io_out[`MPRJ_IO_PADS-1:5], io_out[3:0], la_data_out[63:1], wbs_ack_o, wbs_dat_o[31:0]}),
+
+ // IO Pads
+ .tck(io_in[0]), // test clock on one of the IOs ?
+ .tms(io_in[1]),
+ .tdi(io_in[2]),
+ .trst(io_in[3]),
+ .tdo(io_out[4]),
+ .tdo_paden_o(io_oeb[4])
+ );
+
+endmodule // user_project_wrapper
+`default_nettype wire
\ No newline at end of file
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index 47d92f4..0fb61a0 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -29,9 +29,9 @@
*-------------------------------------------------------------
*/
-module user_project_wrapper #(
- parameter BITS = 32
-)(
+`define MPRJ_IO_PADS 38
+
+module user_project_wrapper (
`ifdef USE_POWER_PINS
inout vdda1, // User area 1 3.3V supply
inout vdda2, // User area 2 3.3V supply
@@ -52,7 +52,7 @@
input [3:0] wbs_sel_i,
input [31:0] wbs_dat_i,
input [31:0] wbs_adr_i,
- output wbs_ack_o,
+ output reg wbs_ack_o,
output [31:0] wbs_dat_o,
// Logic Analyzer Signals
@@ -79,7 +79,7 @@
/* User project is instantiated here */
/*--------------------------------------*/
- user_proj_example mprj (
+ user_proj_top user_proj_top (
`ifdef USE_POWER_PINS
.vdda1(vdda1), // User area 1 3.3V power
.vdda2(vdda2), // User area 2 3.3V power
@@ -93,32 +93,26 @@
// MGMT core clock and reset
- .wb_clk_i(wb_clk_i),
- .wb_rst_i(wb_rst_i),
-
- // MGMT SoC Wishbone Slave
-
- .wbs_cyc_i(wbs_cyc_i),
- .wbs_stb_i(wbs_stb_i),
- .wbs_we_i(wbs_we_i),
- .wbs_sel_i(wbs_sel_i),
- .wbs_adr_i(wbs_adr_i),
- .wbs_dat_i(wbs_dat_i),
- .wbs_ack_o(wbs_ack_o),
- .wbs_dat_o(wbs_dat_o),
+ .clk(wb_clk_i),
+ .rst(wb_rst_i),
// Logic Analyzer
- .la_data_in(la_data_in),
- .la_data_out(la_data_out),
- .la_oen (la_oen),
+ .mc (la_data_in[31:0]),
+ .mp (la_data_in[63:32]),
+ .start (la_data_in[64]),
+ .done (la_data_out[0]),
+ .prod (la_data_out[127:64]),
+ .tie ({io_oeb[`MPRJ_IO_PADS-1:5], io_oeb[3:0], io_out[`MPRJ_IO_PADS-1:5], io_out[3:0], la_data_out[63:1], wbs_ack_o, wbs_dat_o[31:0]}),
- // IO Pads
-
- .io_in (io_in),
- .io_out(io_out),
- .io_oeb(io_oeb)
+ // IO Pads
+ .tck(io_in[0]), // test clock on one of the IOs ?
+ .tms(io_in[1]),
+ .tdi(io_in[2]),
+ .trst(io_in[3]),
+ .tdo(io_out[4]),
+ .tdo_paden_o(io_oeb[4])
);
endmodule // user_project_wrapper
-`default_nettype wire
+`default_nettype wire
\ No newline at end of file