HDLRuby 2.2.16 → 2.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +33 -21
- data/lib/HDLRuby/hdr_samples/rom.rb +2 -2
- data/lib/HDLRuby/hdr_samples/ruby_fir_hw.rb +96 -0
- data/lib/HDLRuby/hdr_samples/with_channel.rb +49 -8
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +3 -2
- data/lib/HDLRuby/hdr_samples/with_linear.rb +48 -25
- data/lib/HDLRuby/hdr_samples/with_loop.rb +69 -0
- data/lib/HDLRuby/hdr_samples/with_memory.rb +13 -3
- data/lib/HDLRuby/hdrcc.rb +8 -12
- data/lib/HDLRuby/hruby_check.rb +25 -1
- data/lib/HDLRuby/hruby_high.rb +6 -0
- data/lib/HDLRuby/hruby_low.rb +43 -9
- data/lib/HDLRuby/hruby_low2c.rb +9 -5
- data/lib/HDLRuby/hruby_low2high.rb +1 -1
- data/lib/HDLRuby/hruby_low2vhd.rb +63 -48
- data/lib/HDLRuby/hruby_low_fix_types.rb +6 -2
- data/lib/HDLRuby/hruby_low_resolve.rb +5 -3
- data/lib/HDLRuby/hruby_low_without_concat.rb +8 -4
- data/lib/HDLRuby/hruby_types.rb +82 -72
- data/lib/HDLRuby/hruby_verilog.rb +9 -1
- data/lib/HDLRuby/sim/hruby_sim.h +7 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +83 -6
- data/lib/HDLRuby/sim/hruby_sim_core.c +2 -0
- data/lib/HDLRuby/std/channel.rb +336 -158
- data/lib/HDLRuby/std/fixpoint.rb +50 -39
- data/lib/HDLRuby/std/linear.rb +68 -0
- data/lib/HDLRuby/std/loop.rb +101 -0
- data/lib/HDLRuby/std/memory.rb +1002 -32
- data/lib/HDLRuby/std/task.rb +850 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6548ba8f8c1572f8aa254b168eab065bc5d0a06ac996d792b4082a9243a2dfc9
|
4
|
+
data.tar.gz: 97891dad52f2454d37755af82cf6d23b2665cccd39a44caff81701921f233931
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6df258eebc8a3448824aca9bf39d24ad98c9302728c2584bb34880b8160b42a00f6b7e0fed68a4097403046e0621bf16c8048c43ce95090254f4e9e6e1ebc079
|
7
|
+
data.tar.gz: 73cc373d53e91a756922c8539f15283f793db0ce6e1b3e7c2ae566ae6e2c19691ee62d7dd3ac5ca1f1e19c61a809ab234aba3c790ae207327f8cd2609c76816f
|
data/README.md
CHANGED
@@ -1301,14 +1301,7 @@ __The vector operator__ `[]` is used for building types representing vectors of
|
|
1301
1301
|
<type>[<range>]
|
1302
1302
|
```
|
1303
1303
|
|
1304
|
-
The `<range>` of a vector type indicates the position of the starting and ending bits
|
1305
|
-
is on the left side of the range, the vector is big endian, otherwise it is little endian. Negative values in a range are also possible and indicate positions bellow the radix point. For example, the following code describes a big-endian fixed-point type with 8 bits above the radix point and 4 bits
|
1306
|
-
bellow:
|
1307
|
-
|
1308
|
-
```ruby
|
1309
|
-
bit[7..-4]
|
1310
|
-
```
|
1311
|
-
|
1304
|
+
The `<range>` of a vector type indicates the position of the starting and ending bits.
|
1312
1305
|
A `n..0` range can also be abbreviated to `n+1`. For instance, the two following types are identical:
|
1313
1306
|
|
1314
1307
|
```ruby
|
@@ -2801,6 +2794,19 @@ bit[4,4].inner :sig
|
|
2801
2794
|
|
2802
2795
|
When performing computation with fixed point types, HDLRuby ensures that the result's decimal point position is correct.
|
2803
2796
|
|
2797
|
+
In addition to the fixed point data type, a method is added to the literal objects (Numeric) to convert them to fixed point representation:
|
2798
|
+
|
2799
|
+
```ruby
|
2800
|
+
<litteral>.to_fix(<number of bits after the decimal point>)
|
2801
|
+
```
|
2802
|
+
|
2803
|
+
For example the following code converts a floating point value to a fixed point value with 16 bits after the decimal point:
|
2804
|
+
|
2805
|
+
```
|
2806
|
+
3.178.to_fix(16)
|
2807
|
+
```
|
2808
|
+
|
2809
|
+
|
2804
2810
|
## Channel
|
2805
2811
|
<a name="channel"></a>
|
2806
2812
|
|
@@ -2809,27 +2815,17 @@ This library provides a unified interface to complex communication protocols thr
|
|
2809
2815
|
### Using a channel
|
2810
2816
|
|
2811
2817
|
A channel is used similarly to a pipe: it has an input where data can be written and an output where data can be read. The ordering of the data and the synchronization depend on the internals of the channel, e.g., a channel can be FIFO or LIFO. The interaction with the channel is done using the following methods:
|
2812
|
-
|
2813
|
-
* `input <name>`: generate ports in the system for reading from the channel amd associate them to `name`
|
2814
|
-
* `output <name>`: generate ports in the system for writing to the channel and associate them to `name`
|
2815
|
-
* `inout <name>`: generate ports in the system for reading and writing to the channel and associate them to `name`
|
2816
|
-
* `inner <name>`: generates inner signals for accessing directly the channel
|
2817
|
-
|
2818
|
-
__Note__: `input`, `output`, `inout` and `inner` for channels work similarly to the ones of data types for declaring signals. In particular, `input`, `output` and `inout` are to be used in systems that do not include the channel and `inner` is to be used in the system that include the channel.
|
2819
|
-
|
2820
|
-
When the channel ports are declared, they can be accessed using the following methods depending on whether they are writing or reading ports:
|
2821
2818
|
|
2822
2819
|
* `write(<args>) <block>`: write to the channel and execute `block` when `write` completes. `args` is a list of arguments required for performing the write that depend on the channel.
|
2823
2820
|
* `read(<args>) <block>`: read the channel and execute `block` when the read completes. `args` is a list of arguments required for performing the write that depend on the channel.
|
2824
2821
|
|
2822
|
+
|
2825
2823
|
For example, a system sending successive 8-bit values through a channel can be described as follows:
|
2826
2824
|
|
2827
2825
|
```ruby
|
2828
2826
|
system :producer8 do |channel|
|
2829
2827
|
# Inputs of the producer: clock and reset.
|
2830
2828
|
input :clk, :rst
|
2831
|
-
# Instantiate the channel ports
|
2832
|
-
channel.output :chi
|
2833
2829
|
# Inner 8-bit counter for generating values.
|
2834
2830
|
[8].inner :counter
|
2835
2831
|
|
@@ -2837,7 +2833,7 @@ system :producer8 do |channel|
|
|
2837
2833
|
par(clk.posedge) do
|
2838
2834
|
hif(rst) { counter <= 0 }
|
2839
2835
|
helse do
|
2840
|
-
|
2836
|
+
channel.write(counter) { counter <= counter + 1 }
|
2841
2837
|
end
|
2842
2838
|
end
|
2843
2839
|
end
|
@@ -2845,6 +2841,22 @@ end
|
|
2845
2841
|
|
2846
2842
|
__Note__: In the code above, the channel is passed as generic argument of the system.
|
2847
2843
|
|
2844
|
+
The access points to a channel can also be handled individually by declaring ports using the following methods:
|
2845
|
+
|
2846
|
+
* `input <name>`: declares a port for reading from the channel and associate them to `name` if any
|
2847
|
+
* `output <name>`: declares a port for writing to the channel and associate them to `name` if any
|
2848
|
+
* `inout <name>`: declares a port for reading and writing to the channel and associate them to `name` if any
|
2849
|
+
|
2850
|
+
Such port can then be accessed using the same `read` and `write` method of a channel, the difference being that they can also be configured for new access procedure using the `wrap` method:
|
2851
|
+
|
2852
|
+
* `wrap(<args>) <code>`: creates a new port whose read or write procedure has the elements of `<args>` and the ones produced by `<code>` assign to the arguments of the read or write procedure.
|
2853
|
+
|
2854
|
+
For example, assuming `mem` is a channel whose read and write access have as argument the target address and data signals, the following code creates a port for always accessing at address 0:
|
2855
|
+
|
2856
|
+
```ruby
|
2857
|
+
addr0 = channel.input.wrap(0)
|
2858
|
+
```
|
2859
|
+
|
2848
2860
|
### Channel branches
|
2849
2861
|
|
2850
2862
|
Some channel may include several branches, they are accessed by name using the following method:
|
@@ -2888,7 +2900,7 @@ Where `name` is the name of the channel and `block` is a procedure block describ
|
|
2888
2900
|
The first argument of the block must be the following:
|
2889
2901
|
- `blk`: the block to execute when the write completes.
|
2890
2902
|
Other arguments can be freely defined, and will be required by the `write` command.
|
2891
|
-
* `brancher(name) <block>`: defines branch named +name+ described in `block`. The content of block can be any content valid for a channel, with the additional
|
2903
|
+
* `brancher(name) <block>`: defines branch named +name+ described in `block`. The content of block can be any content valid for a channel, with the additional possibility to access the internals of the upper channel.
|
2892
2904
|
|
2893
2905
|
For example, a channel implemented by a simple register of generic type `typ`, that can be set to 0 using the `reset` command can be described as follows:
|
2894
2906
|
|
@@ -4,8 +4,8 @@ system :rom4_8 do
|
|
4
4
|
[2..0].input :addr
|
5
5
|
[7..0].output :data0,:data1,:data2
|
6
6
|
|
7
|
-
bit[7..0][0..7].constant content0: [1,2,3,4,5,6,7]
|
8
|
-
bit[7..0][-8].constant content1: [1,2,3,4,5,6,7]
|
7
|
+
bit[7..0][0..7].constant content0: [0,1,2,3,4,5,6,7]
|
8
|
+
bit[7..0][-8].constant content1: [0,1,2,3,4,5,6,7]
|
9
9
|
bit[7..0][-8].constant content2: (8).times.to_a
|
10
10
|
|
11
11
|
data0 <= content0[addr]
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'std/memory.rb'
|
2
|
+
require 'std/linear.rb'
|
3
|
+
# require 'std/timing.rb'
|
4
|
+
|
5
|
+
include HDLRuby::High::Std
|
6
|
+
|
7
|
+
|
8
|
+
system :fir do |typ,iChannel,oChannel,coefs|
|
9
|
+
input :clk, :rst, :req
|
10
|
+
output :ack
|
11
|
+
# Declare the input port.
|
12
|
+
iChannel.input :iPort
|
13
|
+
# Declare the output port.
|
14
|
+
oChannel.output :oPort
|
15
|
+
|
16
|
+
# Declares the data registers.
|
17
|
+
datas = coefs.map.with_index do |coef,id|
|
18
|
+
coef.type.inner :"data_#{id}"
|
19
|
+
end
|
20
|
+
|
21
|
+
inner :req2
|
22
|
+
|
23
|
+
|
24
|
+
# Generate the mac pipeline.
|
25
|
+
mac_np(typ,clk.posedge,req2,ack,
|
26
|
+
datas.map{|data| channel_port(data) },
|
27
|
+
coefs.map{|coef| channel_port(coef) }, oPort)
|
28
|
+
|
29
|
+
# Generate the data transfer through the pipeline.
|
30
|
+
par(clk.posedge) do
|
31
|
+
req2 <= 0
|
32
|
+
hif(rst) { datas.each { |d| d <= 0 } }
|
33
|
+
hif(req) do
|
34
|
+
iPort.read(datas[0]) do
|
35
|
+
# datas.each_cons(2) { |d0,d1| d1 <= d0 }
|
36
|
+
datas[1..-1] <= datas[0..-2]
|
37
|
+
end
|
38
|
+
req2 <= 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
system :work do
|
48
|
+
|
49
|
+
inner :clk,:rst,:req,:ack
|
50
|
+
|
51
|
+
# The input memory.
|
52
|
+
mem_rom([8],8,clk,rst,
|
53
|
+
[_00000001,_00000010,_00000011,_00000100,
|
54
|
+
_00000101,_00000110,_00000111,_00001000]).(:iMem)
|
55
|
+
# The output memory.
|
56
|
+
mem_dual([8],8,clk,rst).(:oMem)
|
57
|
+
# The coefficients.
|
58
|
+
coefs = [_11001100,_00110011,_10101010,_01010101,
|
59
|
+
_11110000,_00001111,_11100011,_00011100]
|
60
|
+
|
61
|
+
# The filter
|
62
|
+
fir([8],iMem.branch(:rinc),oMem.branch(:winc),coefs).(:my_fir).(clk,rst,req,ack)
|
63
|
+
|
64
|
+
# iMem.branch(:rinc).inner :port
|
65
|
+
# [8].inner :a
|
66
|
+
# par(clk.posedge) do
|
67
|
+
# hif(req) { port.read(a) }
|
68
|
+
# end
|
69
|
+
|
70
|
+
timed do
|
71
|
+
req <= 0
|
72
|
+
clk <= 0
|
73
|
+
rst <= 0
|
74
|
+
!10.ns
|
75
|
+
clk <= 1
|
76
|
+
!10.ns
|
77
|
+
clk <= 0
|
78
|
+
rst <= 1
|
79
|
+
!10.ns
|
80
|
+
clk <= 1
|
81
|
+
!10.ns
|
82
|
+
clk <= 0
|
83
|
+
rst <= 0
|
84
|
+
!10.ns
|
85
|
+
clk <= 1
|
86
|
+
!10.ns
|
87
|
+
req <= 1
|
88
|
+
clk <= 0
|
89
|
+
64.times do
|
90
|
+
!10.ns
|
91
|
+
clk <= 1
|
92
|
+
!10.ns
|
93
|
+
clk <= 0
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -63,12 +63,13 @@ end
|
|
63
63
|
|
64
64
|
|
65
65
|
# A system writing indefinitely to a channel.
|
66
|
+
# Checking usage of channel without declaring a port.
|
66
67
|
system :producer8 do |channel|
|
67
|
-
# puts "channel=#{channel}"
|
68
|
+
# puts "channel=#{channel}, channel methods=#{channel.methods}"
|
68
69
|
# Inputs of the producer: clock and reset.
|
69
70
|
input :clk, :rst
|
70
|
-
# Instantiate the channel ports
|
71
|
-
channel.output :ch
|
71
|
+
# # Instantiate the channel ports
|
72
|
+
# channel.output :ch
|
72
73
|
# Inner 8-bit counter for generating values.
|
73
74
|
[8].inner :counter
|
74
75
|
|
@@ -76,7 +77,8 @@ system :producer8 do |channel|
|
|
76
77
|
par(clk.posedge) do
|
77
78
|
hif(rst) { counter <= 0 }
|
78
79
|
helse do
|
79
|
-
ch.write(counter) { counter <= counter + 1 }
|
80
|
+
# ch.write(counter) { counter <= counter + 1 }
|
81
|
+
channel.write(counter) { counter <= counter + 1 }
|
80
82
|
end
|
81
83
|
end
|
82
84
|
end
|
@@ -96,20 +98,59 @@ system :consummer8 do |channel|
|
|
96
98
|
end
|
97
99
|
end
|
98
100
|
|
101
|
+
# A system reading indefinitely from a channel.
|
102
|
+
# Version without port declaration.
|
103
|
+
system :consummer16 do |channel|
|
104
|
+
# Input of the consummer: a clock is enough.
|
105
|
+
input :clk
|
106
|
+
# # Instantiate the channel ports
|
107
|
+
# channel.input :ch
|
108
|
+
# Inner buffer for storing the cunsummed value.
|
109
|
+
[16].inner :buf
|
110
|
+
|
111
|
+
# The value consumption process
|
112
|
+
par(clk.posedge) do
|
113
|
+
# ch.read(buf)
|
114
|
+
channel.read(buf)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
99
118
|
|
100
119
|
# A system testing the handshaker.
|
101
120
|
system :hs_test do
|
102
121
|
input :clk,:rst
|
103
122
|
|
104
|
-
# Declares
|
105
|
-
handshaker([8]).(:
|
123
|
+
# Declares two handshakers
|
124
|
+
handshaker([8]).(:hs0)
|
125
|
+
handshaker([16]).(:hs1)
|
106
126
|
|
107
127
|
# # Sets the reset.
|
108
128
|
# par(rst.posedge) { hs.reset }
|
129
|
+
|
130
|
+
# For the first handshake
|
109
131
|
|
110
132
|
# Instantiate the producer.
|
111
|
-
producer8(
|
133
|
+
producer8(hs0).(:producerI).(clk,rst)
|
112
134
|
|
113
135
|
# Instantiate the consummer.
|
114
|
-
consummer8(
|
136
|
+
consummer8(hs0).(:consummerI).(clk)
|
137
|
+
|
138
|
+
# For the second handshaker
|
139
|
+
|
140
|
+
# Instantiatethe consummer.
|
141
|
+
consummer16(hs1).(:consummer2I).(clk)
|
142
|
+
|
143
|
+
# Produce from within.
|
144
|
+
[16].inner :counter
|
145
|
+
|
146
|
+
# hs1.output :port
|
147
|
+
|
148
|
+
par(clk.posedge) do
|
149
|
+
hif(rst) { counter <= 0 }
|
150
|
+
helse do
|
151
|
+
# port.write(counter) { counter <= counter + 1 }
|
152
|
+
hs1.write(counter) { counter <= counter + 1 }
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
115
156
|
end
|
@@ -15,27 +15,36 @@ system :testmat do
|
|
15
15
|
inner :clk,:rst, :req
|
16
16
|
|
17
17
|
# Input memories
|
18
|
-
mem_dual([8],256,clk,rst, rinc: :rst,winc: :rst).(:memL0)
|
18
|
+
# mem_dual([8],256,clk,rst, rinc: :rst,winc: :rst).(:memL0)
|
19
|
+
# The first memory is 4-bank for testing purpose.
|
20
|
+
mem_bank([8],4,256/4,clk,rst, rinc: :rst,winc: :rst).(:memL0)
|
21
|
+
# The others are standard dual-edge memories.
|
19
22
|
mem_dual([8],256,clk,rst, rinc: :rst,winc: :rst).(:memL1)
|
20
23
|
mem_dual([8],256,clk,rst, rinc: :rst,winc: :rst).(:memR)
|
21
24
|
# Access ports.
|
22
|
-
memL0.branch(:rinc).inner :readL0
|
23
|
-
memL1.branch(:rinc).inner :readL1
|
24
|
-
memR.branch(:rinc).inner :readR
|
25
|
+
# # memL0.branch(:rinc).inner :readL0
|
26
|
+
# # memL1.branch(:rinc).inner :readL1
|
27
|
+
# # memR.branch(:rinc).inner :readR
|
28
|
+
# memL0.branch(:rinc).input :readL0
|
29
|
+
# memL1.branch(:rinc).input :readL1
|
30
|
+
# memR.branch(:rinc).input :readR
|
25
31
|
|
26
32
|
# Prepares the left and acc arrays.
|
27
|
-
lefts = [readL0, readL1]
|
33
|
+
# lefts = [readL0, readL1]
|
34
|
+
lefts = [memL0.branch(:rinc), memL1.branch(:rinc)]
|
28
35
|
|
29
36
|
# Accumulators memory.
|
30
37
|
mem_file([8],2,clk,rst,rinc: :rst).(:memAcc)
|
31
|
-
memAcc.branch(:anum).inner :accs
|
38
|
+
# # memAcc.branch(:anum).inner :accs
|
39
|
+
memAcc.branch(:anum).inout :accs
|
32
40
|
accs_out = [accs.wrap(0), accs.wrap(1)]
|
33
41
|
|
34
42
|
# Layer 0 ack.
|
35
43
|
inner :ack0
|
36
44
|
|
37
45
|
# Instantiate the matrix product.
|
38
|
-
mac_n1([8],clk,req,ack0,lefts,readR,accs_out)
|
46
|
+
# mac_n1([8],clk,req,ack0,lefts,readR,accs_out)
|
47
|
+
mac_n1([8],clk,req,ack0,lefts,memR.branch(:rinc),accs_out)
|
39
48
|
|
40
49
|
# Translation.
|
41
50
|
# Translation memory.
|
@@ -43,10 +52,12 @@ system :testmat do
|
|
43
52
|
# Tarnslation result
|
44
53
|
mem_file([8],2,clk,rst,rinc: :rst).(:memF)
|
45
54
|
# Access ports.
|
46
|
-
memT.branch(:anum).inner :readT
|
47
|
-
memF.branch(:anum).inner :writeF
|
55
|
+
# # memT.branch(:anum).inner :readT
|
56
|
+
# # memF.branch(:anum).inner :writeF
|
57
|
+
memT.branch(:anum).input :readT
|
58
|
+
memF.branch(:anum).output :writeF
|
48
59
|
regRs = [ readT.wrap(0), readT.wrap(1) ]
|
49
|
-
regLs =
|
60
|
+
regLs = accs_out
|
50
61
|
regs = [ writeF.wrap(0), writeF.wrap(1) ]
|
51
62
|
|
52
63
|
# Translater ack.
|
@@ -61,9 +72,10 @@ system :testmat do
|
|
61
72
|
# Input memories.
|
62
73
|
mem_dual([8],2,clk,rst, rinc: :rst,winc: :rst).(:mem2L0)
|
63
74
|
# Access ports.
|
64
|
-
mem2L0.branch(:rinc).inner :read2L0
|
65
|
-
#
|
66
|
-
|
75
|
+
# # mem2L0.branch(:rinc).inner :read2L0
|
76
|
+
# # memF.branch(:rinc).inner :readF
|
77
|
+
# mem2L0.branch(:rinc).input :read2L0
|
78
|
+
# memF.branch(:rinc).input :readF
|
67
79
|
|
68
80
|
# Second layer ack.
|
69
81
|
inner :ack1
|
@@ -73,29 +85,40 @@ system :testmat do
|
|
73
85
|
|
74
86
|
sub do
|
75
87
|
# Instantiate the second matrix product.
|
76
|
-
# mac([8],clk,
|
77
|
-
mac([8],clk,ackT,ack1,
|
88
|
+
# mac([8],clk,ackT,ack1,read2L0,readF,channel_port(res))
|
89
|
+
mac([8],clk,ackT,ack1,mem2L0.branch(:rinc),memF.branch(:rinc),
|
90
|
+
channel_port(res))
|
78
91
|
end
|
79
92
|
|
80
93
|
|
81
94
|
|
82
95
|
# The memory initializer.
|
83
|
-
memL0.branch(:winc).inner :writeL0
|
84
|
-
memL1.branch(:winc).inner :writeL1
|
85
|
-
memR.branch(:winc).inner :writeR
|
86
|
-
memT.branch(:winc).inner :writeT
|
87
|
-
mem2L0.branch(:winc).inner :write2L0
|
96
|
+
# # memL0.branch(:winc).inner :writeL0
|
97
|
+
# # memL1.branch(:winc).inner :writeL1
|
98
|
+
# # memR.branch(:winc).inner :writeR
|
99
|
+
# # memT.branch(:winc).inner :writeT
|
100
|
+
# # mem2L0.branch(:winc).inner :write2L0
|
101
|
+
# memL0.branch(:winc).output :writeL0
|
102
|
+
# memL1.branch(:winc).output :writeL1
|
103
|
+
# memR.branch(:winc).output :writeR
|
104
|
+
# mem2L0.branch(:winc).output :write2L0
|
105
|
+
# memT.branch(:winc).output :writeT
|
88
106
|
inner :fill, :fill2
|
89
107
|
[8].inner :val
|
90
108
|
par(clk.posedge) do
|
91
109
|
hif(fill) do
|
92
|
-
writeL0.write(val)
|
93
|
-
writeL1.write(val+1)
|
94
|
-
writeR.write(val+1)
|
110
|
+
# writeL0.write(val)
|
111
|
+
# writeL1.write(val+1)
|
112
|
+
# writeR.write(val+1)
|
113
|
+
memL0.branch(:winc).write(val)
|
114
|
+
memL1.branch(:winc).write(val+1)
|
115
|
+
memR.branch(:winc).write(val+1)
|
95
116
|
end
|
96
117
|
hif(fill2) do
|
97
|
-
write2L0.write(val+2)
|
98
|
-
writeT.write(val+2)
|
118
|
+
# write2L0.write(val+2)
|
119
|
+
# writeT.write(val+2)
|
120
|
+
mem2L0.branch(:winc).write(val+2)
|
121
|
+
memT.branch(:winc).write(val+2)
|
99
122
|
end
|
100
123
|
end
|
101
124
|
|