Skip to content

Commit 952fd85

Browse files
Merge pull request #2833 from clash-lang/fix-oddr
Fix DDR primitives
2 parents 45d09f6 + c6bda10 commit 952fd85

19 files changed

+1296
-560
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FIXED: `Clash.Explicit.DDR`:
2+
- `ddrIn`: VHDL: Remove data input from sensitivity list of `ddrIn_neg_latch` register as it is superfluous. This should not affect functionality.
3+
- `ddrOut`: VHDL: Fix incorrect usage of `Enable` input when the domain is set to asynchronous resets. Deasserting the `Enable` exhibited wrong behavior before this fix.
4+
FIXED: `Clash.Xilinx.DDR`:
5+
- These primitives only support clocks where the rising edge is the active edge. Using them in a domain with falling active edges now causes an error.
6+
- `oddr`: Fix VHDL and SystemVerilog erroring out during HDL generation
7+
- Symbols in HDL for both `iddr` and `oddr` were renamed to match their function.
8+
FIXED: `Clash.Intel.DDR`:
9+
- These primitives only support clocks where the rising edge is the active edge. Using them in a domain with falling active edges now causes an error.
10+
- Fix rendering HDL. It variously errored out or generated non-working HDL.
11+
- Rendering HDL no longer causes Clash to issue a warning about an argument unused in Haskell but used in the primitive black box.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CHANGED: `Clash.Explicit.DDR`, `Clash.Intel.DDR` and `Clash.Xilinx.DDR`:
2+
- The constraints for the functions have been rewritten to use `DomainPeriod`, which makes them more readable and relaxes unnecessary constraints on the virtual DDR domain. The type-level variables for the domains have been renamed. `dom` is a real domain, `domDDR` is the virtual DDR domain.
3+
- The Xilinx and Intel primitives only support domains where the rising edge is the active edge. This is now enforced at the type level by adding a constraint.
4+
- The Xilinx and Intel primitives now directly support any data type that has a `BitPack` instance.

clash-lib/prims/commonverilog/Clash_Intel_DDR.primitives.yaml

+22-19
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,42 @@
55
- altera_mf
66
type: |-
77
altddioOut#
8-
:: ( HasCallStack -- ARG[0]
9-
, KnownConfi~ fast domf -- ARG[1]
10-
, KnownConfi~ slow doms -- ARG[2]
11-
, KnownNat m ) -- ARG[3]
12-
=> SSymbol deviceFamily -- ARG[4]
13-
-> Clock slow -- ARG[5]
14-
-> Reset slow -- ARG[6]
15-
-> Enable slow -- ARG[7]
16-
-> Signal slow (BitVector m) -- ARG[8]
17-
-> Signal slow (BitVector m) -- ARG[9]
18-
-> Signal fast (BitVector m)
8+
:: forall deviceFamily n dom domDDR
9+
. HasCallStack -- ARG[0]
10+
=> KnownDomain dom -- ARG[1]
11+
=> KnownDomain domDDR -- ARG[2]
12+
=> DomPeriod ~ 2 * ... -- ARG[3]
13+
=> DomEdge ~ Rising -- ARG[4]
14+
=> KnownNat n -- ARG[5]
15+
=> SSymbol deviceFamily -- ARG[6]
16+
-> Clock dom -- ARG[7]
17+
-> Reset dom -- ARG[8]
18+
-> Enable dom -- ARG[9]
19+
-> Signal dom (BitVector n) -- ARG[10]
20+
-> Signal dom (BitVector n) -- ARG[11]
21+
-> Signal domDDR (BitVector n)
1922
template: |-
2023
// altddioOut begin
2124
altddio_out
2225
#(
2326
.extend_oe_disable ("OFF"),
24-
.intended_device_family (~LIT[4]),
27+
.intended_device_family (~LIT[6]),
2528
.invert_output ("OFF"),
2629
.lpm_hint ("UNUSED"),
2730
.lpm_type ("altddio_out"),
2831
.oe_reg ("UNREGISTERED"),
2932
.power_up_high ("OFF"),
3033
.width (~SIZE[~TYPO])
3134
)
32-
~GENSYM[~COMPNAME_ALTDDIO_OUT][7] (~IF ~ISSYNC[2] ~THEN
33-
.sclr (~ARG[6]),
35+
~GENSYM[~COMPNAME_ALTDDIO_OUT][7] (~IF ~ISSYNC[1] ~THEN
36+
.sclr (~ARG[8]),
3437
.aclr (1'b0),~ELSE
35-
.aclr (~ARG[6]),
38+
.aclr (~ARG[8]),
3639
.sclr (1'b0),~FI
37-
.datain_h (~ARG[8]),
38-
.datain_l (~ARG[9]),
39-
.outclock (~ARG[5]),
40-
.outclocken (~IF ~ISACTIVEENABLE[7] ~THEN ~ARG[7] ~ELSE 1'b1 ~FI),
40+
.datain_h (~ARG[10]),
41+
.datain_l (~ARG[11]),
42+
.outclock (~ARG[7]),
43+
.outclocken (~IF ~ISACTIVEENABLE[9] ~THEN ~ARG[9] ~ELSE 1'b1 ~FI),
4144
.dataout (~RESULT),
4245
.aset (1'b0),
4346
.sset (1'b0),

clash-lib/prims/systemverilog/Clash_Explicit_DDR.primitives.yaml

+55-52
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,43 @@
22
name: Clash.Explicit.DDR.ddrIn#
33
kind: Declaration
44
type: |-
5-
ddrIn# :: forall a slow fast n pFast gated synchronous.
6-
( HasCallStack -- ARG[0]
7-
, NFDataX a -- ARG[1]
8-
, KnownConfi~ fast domf -- ARG[2]
9-
, KnownConfi~ slow doms -- ARG[3]
10-
=> Clock slow -- ARG[4], clk
11-
-> Reset slow -- ARG[5], rst
12-
-> Enable slow -- ARG[6], en
13-
-> a -- ARG[7]
14-
-> a -- ARG[8]
15-
-> a -- ARG[9]
16-
-> Signal fast a -- ARG[10]
17-
-> Signal slow (a,a)
5+
ddrIn# :: forall a dom domDDR
6+
. HasCallStack -- ARG[0]
7+
=> NFDataX a -- ARG[1]
8+
=> KnownDomain dom -- ARG[2]
9+
=> KnownDomain domDDR -- ARG[3]
10+
=> DomPeriod ~ 2 * ... -- ARG[4]
11+
=> Clock dom -- ARG[5]
12+
-> Reset dom -- ARG[6]
13+
-> Enable dom -- ARG[7]
14+
-> a -- ARG[8]
15+
-> a -- ARG[9]
16+
-> a -- ARG[10]
17+
-> Signal domDDR a -- ARG[11]
18+
-> Signal dom (a,a)
1819
template: |-
1920
// ddrIn begin
20-
~SIGD[~GENSYM[data_Pos][1]][9];
21-
~SIGD[~GENSYM[data_Neg][2]][9];
22-
~SIGD[~GENSYM[data_Neg_Latch][3]][9];
23-
always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrIn_pos][6]
24-
if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin
25-
~SYM[1] <= ~ARG[8];
26-
end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin
27-
~SYM[1] <= ~ARG[10];
21+
~SIGD[~GENSYM[data_Pos][1]][11];
22+
~SIGD[~GENSYM[data_Neg][2]][11];
23+
~SIGD[~GENSYM[data_Neg_Latch][3]][11];
24+
always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrIn_pos][6]
25+
if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin
26+
~SYM[1] <= ~ARG[9];
27+
end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin
28+
~SYM[1] <= ~ARG[11];
2829
end
2930
end
30-
always @(~IF~ACTIVEEDGE[Rising][2]~THENnegedge~ELSEposedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrIn_neg][7]
31-
if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin
32-
~SYM[2] <= ~ARG[9];
33-
end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin
31+
always @(~IF~ACTIVEEDGE[Rising][2]~THENnegedge~ELSEposedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrIn_neg][7]
32+
if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin
3433
~SYM[2] <= ~ARG[10];
34+
end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin
35+
~SYM[2] <= ~ARG[11];
3536
end
3637
end
37-
always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrIn_neg_latch][8]
38-
if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin
39-
~SYM[3] <= ~ARG[7];
40-
end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin
38+
always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrIn_neg_latch][8]
39+
if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin
40+
~SYM[3] <= ~ARG[8];
41+
end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin
4142
~SYM[3] <= ~SYM[2];
4243
end
4344
end
@@ -49,38 +50,40 @@
4950
kind: Declaration
5051
outputUsage: Blocking
5152
type: |-
52-
ddrOut# :: ( HasCallStack -- ARG[0]
53-
, NFDataX a -- ARG[1]
54-
, KnownConfi~ fast domf -- ARG[2]
55-
, KnownConfi~ slow doms -- ARG[3]
56-
=> Clock slow -- ARG[4]
57-
-> Reset slow -- ARG[5]
58-
-> Enable slow -- ARG[6]
59-
-> a -- ARG[7]
60-
-> Signal slow a -- ARG[8]
61-
-> Signal slow a -- ARG[9]
62-
-> Signal fast a
53+
ddrOut# :: forall a dom domDDR
54+
. HasCallStack -- ARG[0]
55+
=> NFDataX a -- ARG[1]
56+
=> KnownDomain dom -- ARG[2]
57+
=> KnownDomain domDDR -- ARG[3]
58+
=> DomPeriod ~ 2 * ... -- ARG[4]
59+
=> Clock dom -- ARG[5]
60+
-> Reset dom -- ARG[6]
61+
-> Enable dom -- ARG[7]
62+
-> a -- ARG[8]
63+
-> Signal dom a -- ARG[9]
64+
-> Signal dom a -- ARG[10]
65+
-> Signal domDDR a
6366
template: |-
6467
// ddrOut begin
65-
~SIGD[~GENSYM[data_Pos][1]][7];
66-
~SIGD[~GENSYM[data_Neg][2]][7];
67-
always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrOut_pos][5]
68-
if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin
69-
~SYM[1] <= ~ARG[7];
70-
end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin
68+
~SIGD[~GENSYM[data_Pos][1]][8];
69+
~SIGD[~GENSYM[data_Neg][2]][8];
70+
always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrOut_pos][5]
71+
if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin
7172
~SYM[1] <= ~ARG[8];
73+
end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin
74+
~SYM[1] <= ~ARG[9];
7275
end
7376
end
74-
always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrOut_neg][6]
75-
if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin
76-
~SYM[2] <= ~ARG[7];
77-
end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin
78-
~SYM[2] <= ~ARG[9];
77+
always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrOut_neg][6]
78+
if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin
79+
~SYM[2] <= ~ARG[8];
80+
end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin
81+
~SYM[2] <= ~ARG[10];
7982
end
8083
end
8184
8285
always @(*) begin
83-
if (~ARG[4]) begin
86+
if (~ARG[5]) begin
8487
~RESULT = ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[1]~ELSE~SYM[2]~FI;
8588
end else begin
8689
~RESULT = ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[2]~ELSE~SYM[1]~FI;

clash-lib/prims/systemverilog/Clash_Intel_DDR.primitives.yaml

+25-22
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,45 @@
11
- BlackBox:
2-
name: Clash.Intel.DDR.altddioIn
2+
name: Clash.Intel.DDR.altddioIn#
33
kind: Declaration
44
libraries:
55
- altera_mf
66
type: |-
7-
altddioIn
8-
:: ( HasCallStack -- ARG[0]
9-
, KnownConfi~ fast domf -- ARG[1]
10-
, KnownConfi~ slow doms -- ARG[2]
11-
, KnownNat m ) -- ARG[3]
12-
=> SSymbol deviceFamily -- ARG[4]
13-
-> Clock slow -- ARG[5]
14-
-> Reset slow -- ARG[6]
15-
-> Enable slow -- ARG[7]
16-
-> Signal fast (BitVector m) -- ARG[8]
17-
-> Signal slow (BitVector m,BitVector m)
7+
altddioIn#
8+
:: forall deviceFamily n dom domDDR
9+
. HasCallStack -- ARG[0]
10+
=> KnownDomain dom -- ARG[1]
11+
=> KnownDomain domDDR -- ARG[2]
12+
=> DomPeriod ~ 2 * ... -- ARG[3]
13+
=> DomEdge ~ Rising -- ARG[4]
14+
=> KnownNat n -- ARG[5]
15+
=> SSymbol deviceFamily -- ARG[6]
16+
-> Clock dom -- ARG[7]
17+
-> Reset dom -- ARG[8]
18+
-> Enable dom -- ARG[9]
19+
-> Signal domDDR (BitVector n) -- ARG[10]
20+
-> Signal dom (BitVector n, BitVector n)
1821
template: |-
1922
// altddioIn begin
20-
~SIGD[~GENSYM[dataout_l][1]][8];
21-
~SIGD[~GENSYM[dataout_h][2]][8];
23+
~SIGD[~GENSYM[dataout_l][1]][10];
24+
~SIGD[~GENSYM[dataout_h][2]][10];
2225
2326
altddio_in
2427
#(
25-
.intended_device_family (~LIT[4]),
28+
.intended_device_family (~LIT[6]),
2629
.invert_input_clocks ("OFF"),
2730
.lpm_hint ("UNUSED"),
2831
.lpm_type ("altddio_in"),
2932
.power_up_high ("OFF"),
30-
.width (~SIZE[~TYP[8]])
33+
.width (~SIZE[~TYP[10]])
3134
)
32-
~GENSYM[~COMPNAME_ALTDDIO_IN][7] (~IF ~ISSYNC[2] ~THEN
33-
.sclr (~ARG[6]),
35+
~GENSYM[~COMPNAME_ALTDDIO_IN][7] (~IF ~ISSYNC[1] ~THEN
36+
.sclr (~ARG[8]),
3437
.aclr (1'b0),~ELSE
35-
.aclr (~ARG[6]),
38+
.aclr (~ARG[8]),
3639
.sclr (1'b0),~FI
37-
.datain (~ARG[8]),
38-
.inclock (~ARG[5]),
39-
.inclocken (~IF ~ISACTIVEENABLE[7] ~THEN~ARG[7]~ELSE1'b1,~FI),
40+
.datain (~ARG[10]),
41+
.inclock (~ARG[7]),
42+
.inclocken (~IF ~ISACTIVEENABLE[9] ~THEN~ARG[9]~ELSE1'b1~FI),
4043
.dataout_h (~SYM[2]),
4144
.dataout_l (~SYM[1]),
4245
.aset (1'b0),

0 commit comments

Comments
 (0)