-
Notifications
You must be signed in to change notification settings - Fork 4
/
features.w
135 lines (100 loc) · 3.74 KB
/
features.w
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// This design demonstrates some features of Wyre.
subtract_module(x $8, y $8) {
out output := x - y
}
// Declare a module with inputs clk (1 bit wide), a and b (both 4 bits wide)
some_module(clk $1, a $4, b $4) {
// Wires
some_wire := a + b // some_wire is inferred to be $4 (i.e. 4 bits wide)
some_wire2 $4 := a + b // Equivalent
// Literals
foo := '10101010 // Bit literal. foo is inferred to be $8
bar $8 := 3 // Need to specify type because '3' doesn't have a specific width
bar2 := 3_$8 // _$N suffix can be used to treat number as specific width
hex $4 := 0xa // Need to specify type for same reason as above
hex2 := 0xa_$4 // Can use _$N suffix
// Outputs
out some_output := a | b // some_output is inferred to be $4
out some_output2 $4 := a | b // Equivalent
// Registers
reg some_reg = '1111 // some_reg is inferred to be $4; initialized to '1111 (15)
reg some_reg2 $4 = '1111 // Equivalent
reg some_reg3 $4 // Initial value is 0 if not specified
// Register updates; must happen inside clock statement (posedge/negedge keyword)
posedge clk {
some_reg <= 1
// Conditional updates
if a == '0101 {
some_reg2 <= 2
reg other_reg $4 <= 3 // Can declare registers anywhere; can combine declaration and update
nested_wire := some_reg + other_reg // Can declare wires anywhere (unaffected by clock and if statement)
} else {
some_reg2 <= 0xf
}
}
negedge clk {
some_reg3 <= b
}
// Unary operators
negated := -a
inverted := ~a
extended_wire $32 := zx a // a is zero extended to 32 bits total
// Binary operators
op_add := a + b
op_subtract := a - b
op_and := a & b
op_or := a | b
op_xor := a ^ b
op_compare := a == b // Or: != < <= > >=
op_shl := a << 1
op_shr := a >> 1
// Ternary operator
c := some_wire == 3 ? a : b
// Select & concatenate bits
msb := a[3]
rest := a[2:0]
recombined := { a[3], a[2:0] }
repeated_wire := rep(a[2:0], 10) // Use builtin function rep to repeat values. repeated_wire is inferred to be $30
// match
match_result := match some_wire[1:0] {
'00: a & b
'01: a | b
'10: a ^ b
'11: a & ~b
}
// Module instantiation
sub := subtract_module(x: 8, y: 5) // Connect inputs x and y
baz := sub.output // Use module output, type of baz is inferred to be $8
sub2 := subtract_module(x: ---, y: 5) // All inputs must be specified; to leave disconnected, use ---
sub3 := subtract_module(x: 'xxxxxx00, y: 5) // Or use bit literal with "don't care" value (x) for partially disconnected
}
// Module with a static input and a normal input
// The static input must be assigned a value that is constant at initialization time, and won't be part of the final hardware design
another_module(
#some_static_input $32
q $32
) {
// Static variables
#lower_half := #some_static_input[15:0] // Constant at initialization time, won't be part of final hardware design
// Define data block; #data is inferred to be $128
#data := [
c0cac01ac0cac01a
c0cac01ac0cac01a
]
// Swizzle #data; even bits followed by odd bits; swizzle(target, seq_size, step, block_size) (for details, see compiler/tape.mu, swizzle(...)).
#sw := swizzle(#data, 1, 2, 128)
// Divide #sw into two chunks ($64 each); chunk(target, chunk_index, number_of_chunks)
#part_a := chunk(#sw, 0, 2)
#part_b := chunk(#sw, 1, 2)
}
// Note: as you can see above, module inputs can be separated by newlines if you prefer. This also works for module instantiations.
// Constants are global, and must be declared outside a module
some_constant $10 := 100
some_constant2 := 100 // Can omit type if you prefer
// Blackbox module declaration, for external modules. Example: a global buffer from Lattice iCE40 FPGA.
SB_GB blackbox(
USER_SIGNAL_TO_GLOBAL_BUFFER $1
) {
// Outputs are declared inside module body
out GLOBAL_BUFFER_OUTPUT $1
}