blob: c7191b1bf42f7494cd6106f5bbc315d8ea93628b [file] [log] [blame]
// 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, p);
parameter size = 32;
input clk, rst;
input y;
input[size-1:0] x;
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]), .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]), .sum(pp[i]));
end endgenerate
TCMP tcmp (.clk(clk), .rst(rst), .a(x[size-1]&y), .s(pp[size-1]));
endmodule
module TCMP(clk, rst, a, s);
input clk, rst;
input a;
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 begin
//Sequential logic goes here.
z <= a | z;
s <= a ^ z;
end
end
endmodule
module CSADD(clk, rst, x, y, sum);
input clk, rst;
input x, y;
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 begin
//Sequential logic goes here.
sum <= hsum2;
sc <= hco1 ^ hco2;
end
end
endmodule
/*
module spm_tb;
//Inputs
reg clk;
reg rst;
reg [7: 0] x;
reg[7:0] Y;
reg[15:0] P;
//Outputs
wire p;
reg[3:0] cnt;
//Instantiation of Unit Under Test
spm #(8) uut (
.clk(clk),
.rst(rst),
.y(Y[0]),
.x(x),
.p(p)
);
always #5 clk = ~clk;
always @ (posedge clk)
if(rst) Y = -50;
else Y <= {1'b0,Y[7:1]};
always @ (posedge clk)
if(rst) P = 0;
else P <= {p, P[15:1]};
always @ (posedge clk)
if(rst) cnt = 0;
else cnt <= cnt + 1;
initial begin
//Inputs initialization
clk = 0;
rst = 0;
x = 50;
//Reset
#20 rst = 1;
#20 rst = 0;
#1000;
$finish;
end
endmodule
*/