aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/xilinx/cells_sim.v
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2019-08-06 13:23:42 +0100
committerDavid Shah <dave@ds0.me>2019-08-06 13:23:42 +0100
commit7a563d0b92b3b5c837fca9647a43a01e258072a5 (patch)
treeabf273b54175112965d2c51624a08db2ad14c63b /techlibs/xilinx/cells_sim.v
parentc39b1a6fcf648203df10d640c72e073f455ddc32 (diff)
downloadyosys-7a563d0b92b3b5c837fca9647a43a01e258072a5.tar.gz
yosys-7a563d0b92b3b5c837fca9647a43a01e258072a5.tar.bz2
yosys-7a563d0b92b3b5c837fca9647a43a01e258072a5.zip
[wip] DSP48E1 sim model improvements
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'techlibs/xilinx/cells_sim.v')
-rw-r--r--techlibs/xilinx/cells_sim.v83
1 files changed, 75 insertions, 8 deletions
diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v
index 33b2a8f62..9437a057b 100644
--- a/techlibs/xilinx/cells_sim.v
+++ b/techlibs/xilinx/cells_sim.v
@@ -494,14 +494,81 @@ module DSP48E1 (
`endif
end
- reg signed [29:0] Ar;
- reg signed [17:0] Br;
+ reg signed [29:0] Ar1, Ar2;
+ reg signed [24:0] Dr;
+ reg signed [17:0] Br1, Br2;
reg signed [47:0] Pr;
+ reg [4:0] INMODEr;
generate
- if (AREG == 1) begin always @(posedge CLK) if (CEA2) Ar <= A; end
- else always @* Ar <= A;
- if (BREG == 1) begin always @(posedge CLK) if (CEB2) Br <= B; end
- else always @* Br <= B;
+ if (AREG == 2) begin
+ always @(posedge CLK)
+ if (RSTA) begin
+ Ar1 <= 30'b0;
+ Ar2 <= 30'b0;
+ end else begin
+ if (CEA1) Ar1 <= A;
+ if (CEA2) Ar2 <= Ar1;
+ end
+ end else if (AREG == 1) begin
+ always @(posedge CLK)
+ if (RSTA) begin
+ Ar1 <= 30'b0;
+ Ar2 <= 30'b0;
+ end else begin
+ if (CEA1) Ar1 <= A;
+ if (CEA2) Ar2 <= A;
+ end
+ end else begin
+ always @* Ar1 <= A;
+ always @* Ar2 <= A;
+ end
+
+ if (BREG == 2) begin
+ always @(posedge CLK)
+ if (RSTB) begin
+ Br1 <= 18'b0;
+ Br2 <= 18'b0;
+ end else begin
+ if (CEB1) Br1 <= B;
+ if (CEB2) Br2 <= Br1;
+ end
+ end else if (AREG == 1) begin
+ always @(posedge CLK)
+ if (RSTB) begin
+ Br1 <= 18'b0;
+ Br2 <= 18'b0;
+ end else begin
+ if (CEB1) Br1 <= B;
+ if (CEB2) Br2 <= B;
+ end
+ end else begin
+ always @* Br1 <= B;
+ always @* Br2 <= B;
+ end
+
+ if (DREG == 1) begin always @(posedge CLK) if (RSTD) Dr <= 25'b0; else if (CED) Dr <= D; end
+ else always @* Dr <= D;
+
+ if (INMODEREG == 1) begin always @(posedge CLK) if (RSTINMODE) INMODEr <= 5'b0; else if (CEINMODE) INMODEr <= INMODE; end
+ else always @* INMODEr <= INMODE;
+ endgenerate
+
+ wire signed [29:0] Ar12_muxed = INMODEr[0] ? Ar1 : Ar2;
+ wire signed [24:0] Ar12_gated = INMODEr[1] ? 25'b0 : Ar12_muxed;
+ wire signed [24:0] Dr_gated = INMODEr[2] ? Dr : 25'b0;
+ wire signed [24:0] AD_result = INMODEr[3] ? (Dr_gated - Ar12_gated) : (Dr_gated + Ar12_gated);
+ reg signed [24:0] ADr;
+
+ generate
+ if (ADREG == 1) begin always @(posedge CLK) if (RSTD) ADr <= 25'b0; else if (CEAD) ADr <= AD_result; end
+ else always @* ADr <= AD_result;
+ endgenerate
+
+ wire signed [24:0] A_MULT;
+ wire signed [24:0] B_MULT = INMODEr[4] ? Br1 : Br2;
+ generate
+ if (USE_DPORT == "TRUE") assign A_MULT = ADr;
+ else assign A_MULT = Ar12_gated;
endgenerate
always @* begin
@@ -516,11 +583,11 @@ module DSP48E1 (
if (PCIN != 48'b0) $fatal(1, "Unsupported PCIN value");
if (CARRYIN != 1'b0) $fatal(1, "Unsupported CARRYIN value");
`endif
- Pr[42:0] <= $signed(Ar[24:0]) * Br;
+ Pr[42:0] <= A_MULT * B_MULT;
end
generate
- if (PREG == 1) begin always @(posedge CLK) if (CEP) P <= Pr; end
+ if (PREG == 1) begin always @(posedge CLK) if (RSTP) P <= 48'b0; else if (CEP) P <= Pr; end
else always @* P <= Pr;
endgenerate