Skip to content

Commit

Permalink
Merge pull request #29 from litghost/fix_carry_techmap
Browse files Browse the repository at this point in the history
Dedicated top of carry pin is sourced from O[Y_WIDTH].
  • Loading branch information
litghost authored May 30, 2019
2 parents b10f244 + f3f0943 commit 8d943b4
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 3 deletions.
15 changes: 12 additions & 3 deletions techlibs/xilinx/arith_map.v
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,18 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO);
assign Y[Y_WIDTH-1:0] = O[Y_WIDTH-1:0];
assign CO[Y_WIDTH-2:0] = CO_FABRIC[Y_WIDTH-2:0];

// Use a dedicated CO pin (e.g. no O pin) to avoid [ABCD]MUX congestion
// for top of carry.
assign CO[Y_WIDTH-1] = CO_FABRIC[Y_WIDTH];
// Use a dedicated O pin (e.g. no other CARRY4 pin) to avoid [ABCD]MUX
// congestion for top of carry.
//
// Note:
//
// O[N] = CO[N-1] ^ S[N]
//
// So given S[N] = 0:
//
// O[N] = CO[N-1]
//
assign CO[Y_WIDTH-1] = O[Y_WIDTH];

genvar i;
generate for (i = 0; i < CARRY4_COUNT; i = i + 1) begin:slice
Expand Down
29 changes: 29 additions & 0 deletions techlibs/xilinx/tests/test_arith.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

set -ex

# Test base testbench
iverilog -DVCDFILE=\"test_arith_no_synth.vcd\" -T typ -o test_arith_no_synth \
test_arith_tb.v test_arith.v
vvp -N test_arith_no_synth

# Test Xilinx flow
../../../yosys -v2 -l test_arith_xilinx.log -p synth_xilinx \
-o test_arith_xilinx.v \
test_arith.v
iverilog -DVCDFILE=\"test_arith_xilinx.vcd\" -T typ -o test_arith_xilinx \
test_arith_tb.v test_arith_xilinx.v \
../cells_sim.v
vvp -N test_arith_xilinx

# Test Xilinx (VPR) flow
../../../yosys -v2 -l test_arith_xilinx_vpr.log -p "synth_xilinx -vpr" \
-o test_arith_xilinx_vpr.v \
test_arith.v
iverilog \
-D_EXPLICIT_CARRY \
-DVCDFILE=\"test_arith_xilinx_vpr.vcd\" -T typ \
-o test_arith_xilinx_vpr \
test_arith_tb.v test_arith_xilinx_vpr.v \
../cells_sim.v
vvp -N test_arith_xilinx_vpr
18 changes: 18 additions & 0 deletions techlibs/xilinx/tests/test_arith.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module test_arith(
input [7:0] a,
input [7:0] b,
output [7:0] add,
output [0:0] add_cout,
output [7:0] minus,
output [0:0] minus_cout,
output threshold
);

parameter INCREMENT = 8;
parameter THRESHOLD = 16;

assign {add_cout, add} = a + b;
assign {minus_cout, minus} = a - b;
assign threshold = (a + INCREMENT) >= THRESHOLD;

endmodule
90 changes: 90 additions & 0 deletions techlibs/xilinx/tests/test_arith_tb.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
`timescale 1ns/1ps
`default_nettype none

`ifndef VCDFILE
`define VCDFILE "test_arith_tb.vcd"
`endif

module test;

task tbassert(input a, input reg [512:0] s);
begin
if (a==0) begin
$display("**********************************************************");
$display("* ASSERT FAILURE (@%d): %-s", $time, s);
$display("**********************************************************");
$dumpflush;
$finish_and_return(-1);
end
end
endtask

reg [7:0] a = 0;
reg [7:0] b = 0;
wire [7:0] add;
wire add_cout;
wire [7:0] minus;
wire minus_cout;
wire threshold;

test_arith #(
.INCREMENT(8),
.THRESHOLD(16)
) unt (
.a(a),
.b(b),
.add(add),
.add_cout(add_cout),
.minus(minus),
.minus_cout(minus_cout),
.threshold(threshold)
);

initial begin
$dumpfile(`VCDFILE);
$dumpvars;
#0.9
a = 8'b0000_0000;
b = 8'b0000_0000;
#0.1
tbassert(add == 8'b0000_0000, "zero add");
tbassert(add_cout == 1'b0, "zero add carry");
tbassert(minus == 8'b0000_0000, "zero subtract");
tbassert(minus_cout == 1'b0, "zero subtract carry");
tbassert(threshold == 1'b0, "threshold not met");
#0.9 // 2
a = 8'b0000_0001;
b = 8'b0000_0001;
#0.1
tbassert(add == 8'b0000_0010, "simple add");
tbassert(add_cout == 1'b0, "simple add carry");
tbassert(minus == 8'b0000_0000, "simple subtract");
tbassert(minus_cout == 1'b0, "simple subtract carry");
#0.9 // 3
a = 8'b1111_1111;
b = 8'b0000_0001;
#0.1
tbassert(add == 8'b0000_0000, "overflow add");
tbassert(add_cout == 1'b1, "overflow add carry");
tbassert(minus == 8'b1111_1110, "simple subtract carry 2");
tbassert(minus_cout == 1'b0, "simple subtract carry 2");
#0.9 // 4
a = 8'b0000_0001;
b = 8'b1111_1111;
#0.1
tbassert(add == 8'b0000_0000, "overflow add 2");
tbassert(add_cout == 1'b1, "overflow add 2 carry");
tbassert(minus == 8'b0000_0010, "underflow subtract");
tbassert(minus_cout == 1'b1, "underflow subtract carry");
#0.9 // 5
a = 8'd8;
#0.1
tbassert(threshold, "threshold met");
#0.9 // 6
a = 8'd7;
#0.1
tbassert(!threshold, "threshold not met");
#1 $finish;
end

endmodule

0 comments on commit 8d943b4

Please sign in to comment.