File: ql_dsp_macc.pmg

package info (click to toggle)
yosys 0.52-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 69,796 kB
  • sloc: ansic: 696,955; cpp: 239,736; python: 14,617; yacc: 3,529; sh: 2,175; makefile: 1,945; lex: 697; perl: 445; javascript: 323; tcl: 162; vhdl: 115
file content (77 lines) | stat: -rw-r--r-- 2,306 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
pattern ql_dsp_macc
// Rough sketch: (mux is optional)
//
//               /-----------------------\
//               |                       |
//              \ /                      |
//   mul ----> add -----> mux -----> ff -+---->
//         |              /\
//         |              |
//          --------------

state <IdString> add_ba
state <IdString> mux_ab

// Is the output taken from before or after the FF?
state <bool> output_registered

// Is there a mux in the pattern?
state <bool> mux_in_pattern

code mux_in_pattern
    mux_in_pattern = false;
    branch;
    mux_in_pattern = true;
endcode

// The multiplier is at the center of our pattern
match mul
    select mul->type.in($mul)
    // It has either two or three consumers depending on whether there's a mux
    // in the pattern or not
    select nusers(port(mul, \Y)) <= 3
    filter nusers(port(mul, \Y)) == (mux_in_pattern ? 3 : 2)
endmatch

code output_registered
    output_registered = false;
    branch;
    output_registered = true;
endcode

match add
    select add->type.in($add, $sub)
    choice <IdString> AB {\A, \B}
    define <IdString> BA (AB == \A ? \B : \A)
    // One input to the adder is fed by the multiplier
    index <SigSpec> port(add, AB) === port(mul, \Y)
    // Save the other input port, it needs to be fed by the flip-flop
    set add_ba BA
    // Adder has either two or three consumers; it will have three consumers
    // IFF there's no mux in the pattern and the multiplier-accumulator result
    // is taken unregistered
    filter nusers(port(add, \Y)) == (!mux_in_pattern && !output_registered ? 3 : 2)
endmatch

match mux
    if mux_in_pattern
    select mux->type.in($mux)
    choice <IdString> AB {\A, \B}
    define <IdString> BA (AB == \A ? \B : \A)
    index <SigSpec> port(mux, AB) === port(mul, \Y)
    index <SigSpec> port(mux, BA) === port(add, \Y)
    filter nusers(port(mux, \Y)) == (output_registered ? 2 : 3)
    set mux_ab AB
endmatch

match ff
    select ff->type.in($dff, $adff, $dffe, $adffe)
    select param(ff, \CLK_POLARITY).as_bool()
    index <SigSpec> port(ff, \D) === mux_in_pattern ? port(mux, \Y) : port(add, \Y);
    index <SigSpec> port(ff, \Q) === port(add, add_ba)
    filter nusers(port(ff, \Q)) == (output_registered ? 3 : 2)
endmatch

code
    accept;
endcode