HDLRuby 2.4.26 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/HDLRuby/drivers/xcd.rb +79 -0
- data/lib/HDLRuby/drivers/xcd/dummy.xcd +4 -0
- data/lib/HDLRuby/hdr_samples/dff_properties.rb +19 -0
- data/lib/HDLRuby/hdr_samples/dff_unit.rb +54 -0
- data/lib/HDLRuby/hdr_samples/seqpar_bench.rb +59 -0
- data/lib/HDLRuby/hdrcc.rb +104 -22
- data/lib/HDLRuby/hruby_decorator.rb +248 -0
- data/lib/HDLRuby/hruby_high.rb +256 -67
- data/lib/HDLRuby/hruby_low.rb +511 -0
- data/lib/HDLRuby/hruby_low2c.rb +67 -0
- data/lib/HDLRuby/hruby_low_without_parinseq.rb +151 -0
- data/lib/HDLRuby/hruby_unit.rb +43 -0
- data/lib/HDLRuby/hruby_verilog.rb +260 -130
- data/lib/HDLRuby/std/linear.rb +5 -11
- data/lib/HDLRuby/template_expander.rb +61 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53e83131d2fb3a3f03c085a3139a69d70f4422ade7be950d009e97e17bb92490
|
4
|
+
data.tar.gz: dcbbcbf3bd1e5aa43ac359e502dc0da6dec886d115371f3b2fceead01bcaa9d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1656a5763fef86bd1b8c01eff8d377cc94ff3145889fd486fac99ac7d86b6f6671a30e040679f81da6a76bc08ee09ff5babd11cae72fc8adb721f0258e724fb9
|
7
|
+
data.tar.gz: 8f83372948477da9374abf302ab3910d73b434b22aa020b25071f2ed9127dc7ee95b3c6959952bd9ec008f1ff17327c7edc9e1b9584d1437a530a753b0886f4d
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "HDLRuby/template_expander"
|
2
|
+
|
3
|
+
##
|
4
|
+
# XCD file generator from 'xcd' properties
|
5
|
+
##########################################
|
6
|
+
|
7
|
+
|
8
|
+
# Generates a xcd file from the HDLRuby objects from +top+ using
|
9
|
+
# their 'xcd' properties.
|
10
|
+
# The file is saved in +path+ directory.
|
11
|
+
def xcd_generator(top, path)
|
12
|
+
# Ensure top is a system.
|
13
|
+
if top.is_a?(HDLRuby::Low::SystemI) then
|
14
|
+
top = top.systemT
|
15
|
+
elsif !top.is_a?(HDLRuby::Low::SystemT) then
|
16
|
+
raise "The 'xcd_generator' driver can only be applied on SystemT objects."
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get the name of the resulting file if any.
|
20
|
+
if (top.properties.key?(:xcd_file)) then
|
21
|
+
xcd_file = top.properties[:xcd_file].join
|
22
|
+
else
|
23
|
+
# Default file name.
|
24
|
+
xcd_file = "default.xcd"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Get the target template.
|
28
|
+
xcd_target = top.properties[:xcd_target].join
|
29
|
+
xcd_target_name = xcd_target
|
30
|
+
xcd_target_name += ".xcd" unless xcd_target_name.end_with?(".xcd")
|
31
|
+
xcd_target_tries = [ xcd_target_name,
|
32
|
+
File.join(path,xcd_target_name),
|
33
|
+
File.join(File.dirname(__FILE__),"xcd",xcd_target_name) ]
|
34
|
+
xcd_target_file = xcd_target_tries.find { |fname| File.exist?(fname) }
|
35
|
+
unless xcd_target_file then
|
36
|
+
raise "XCD target template not found for #{xcd_target}."
|
37
|
+
end
|
38
|
+
# Load the template.
|
39
|
+
template = File.read(xcd_target_file)
|
40
|
+
|
41
|
+
# Gather the signals by xcd key.
|
42
|
+
xcd2sig = top.each_signal.reduce([]) do |ar,sig|
|
43
|
+
ar += sig.properties.each_with_key(:xcd).map do |val|
|
44
|
+
[val,sig.name.to_s]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Create the template expander that will generate the xcd file.
|
49
|
+
expander = TemplateExpander.new([
|
50
|
+
[ /^\?.*(\n|\z)/, proc do |str| # Signal link to port
|
51
|
+
if xcd2sig.any? do |match,rep|
|
52
|
+
if str.include?(match) then
|
53
|
+
str = str.gsub("<>",rep)[1..-1]
|
54
|
+
else
|
55
|
+
false
|
56
|
+
end
|
57
|
+
end then
|
58
|
+
str
|
59
|
+
else
|
60
|
+
""
|
61
|
+
end
|
62
|
+
end ]
|
63
|
+
])
|
64
|
+
|
65
|
+
# # Generate the xcd file.
|
66
|
+
# File.open(File.join(path,xcd_file),"w") do |file|
|
67
|
+
# # Generate the signals mapping.
|
68
|
+
# top.each_signal do |signal|
|
69
|
+
# signal.properties.each_with_key(:xcd) do |value|
|
70
|
+
# file << "#{value}\n"
|
71
|
+
# end
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
|
75
|
+
# Generate the xcd file.
|
76
|
+
File.open(File.join(path,xcd_file),"w") do |file|
|
77
|
+
expander.expand(template,file)
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# A simple D-FF
|
2
|
+
system :dff do
|
3
|
+
input :clk, :rst, :d
|
4
|
+
output :q, :qb
|
5
|
+
|
6
|
+
qb <= ~q
|
7
|
+
|
8
|
+
par(clk.posedge) { q <= d & ~rst }
|
9
|
+
|
10
|
+
clk.properties[:xcd] = "CLK"
|
11
|
+
rst.properties[:xcd] = "RST"
|
12
|
+
d.properties[:xcd] = "PORT0"
|
13
|
+
q.properties[:xcd] = "PORT1"
|
14
|
+
qb.properties[:xcd] = "PORT2"
|
15
|
+
cur_system.properties[:xcd_target] = "dummy"
|
16
|
+
cur_system.properties[:xcd_file] = "dff.xcd"
|
17
|
+
cur_system.properties[:post_driver] = "drivers/xcd.rb", :xcd_generator
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Testing HDLRuby unit test.
|
2
|
+
# require 'hruby_unit.rb'
|
3
|
+
|
4
|
+
# Declare multiple simple dff-systems and their corresponding test.
|
5
|
+
|
6
|
+
1.times do |i|
|
7
|
+
|
8
|
+
# A simple D-FF
|
9
|
+
system:"dff#{i}" do
|
10
|
+
input :clk, :rst, :d
|
11
|
+
output :q, :qb
|
12
|
+
|
13
|
+
qb <= ~q
|
14
|
+
|
15
|
+
par(clk.posedge) { q <= d & ~rst }
|
16
|
+
end
|
17
|
+
|
18
|
+
# Code for testing it.
|
19
|
+
Unit.system :"test_dff#{i}" do
|
20
|
+
inner :clk, :rst, :d, :q, :qb
|
21
|
+
|
22
|
+
send(:"dff#{i}",:dffI).(clk,rst,d,q,qb)
|
23
|
+
|
24
|
+
timed do
|
25
|
+
clk <= 0
|
26
|
+
rst <= 0
|
27
|
+
d <= 0
|
28
|
+
!10.ns
|
29
|
+
clk <= 1
|
30
|
+
!10.ns
|
31
|
+
clk <= 0
|
32
|
+
rst <= 1
|
33
|
+
!10.ns
|
34
|
+
clk <= 1
|
35
|
+
!10.ns
|
36
|
+
clk <= 0
|
37
|
+
rst <= 0
|
38
|
+
!10.ns
|
39
|
+
clk <= 1
|
40
|
+
!10.ns
|
41
|
+
clk <= 0
|
42
|
+
d <= 1
|
43
|
+
!10.ns
|
44
|
+
clk <= 1
|
45
|
+
!10.ns
|
46
|
+
clk <= 0
|
47
|
+
d <= 0
|
48
|
+
!10.ns
|
49
|
+
clk <= 1
|
50
|
+
!10.ns
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# require "../hruby_low2c.rb"
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
# A system for testing the execution of par block in seq block.
|
6
|
+
system :seqpar_bench do
|
7
|
+
|
8
|
+
inner :rst, :clk
|
9
|
+
signed[8].inner :a, :b, :c, :d
|
10
|
+
signed[8].inner :out
|
11
|
+
|
12
|
+
seq(clk.posedge) do
|
13
|
+
hif(rst) do
|
14
|
+
a <= 0
|
15
|
+
b <= 0
|
16
|
+
c <= 0
|
17
|
+
d <= 0
|
18
|
+
end
|
19
|
+
helse do
|
20
|
+
a <= a + 1
|
21
|
+
b <= a + 2
|
22
|
+
par do
|
23
|
+
c <= b + 3
|
24
|
+
d <= c + 4
|
25
|
+
end
|
26
|
+
a <= d + 5
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
out <= a
|
31
|
+
|
32
|
+
timed do
|
33
|
+
clk <= 0
|
34
|
+
rst <= 0
|
35
|
+
!20.ns
|
36
|
+
clk <= 1
|
37
|
+
!20.ns
|
38
|
+
clk <= 0
|
39
|
+
rst <= 1
|
40
|
+
!20.ns
|
41
|
+
clk <= 1
|
42
|
+
!20.ns
|
43
|
+
clk <= 0
|
44
|
+
rst <= 0
|
45
|
+
!20.ns
|
46
|
+
clk <= 1
|
47
|
+
!20.ns
|
48
|
+
clk <= 0
|
49
|
+
!20.ns
|
50
|
+
clk <= 1
|
51
|
+
!20.ns
|
52
|
+
clk <= 0
|
53
|
+
!20.ns
|
54
|
+
clk <= 1
|
55
|
+
!20.ns
|
56
|
+
clk <= 0
|
57
|
+
!20.ns
|
58
|
+
end
|
59
|
+
end
|
data/lib/HDLRuby/hdrcc.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
|
+
require 'tempfile'
|
4
5
|
require 'HDLRuby'
|
5
6
|
require 'HDLRuby/hruby_check.rb'
|
6
7
|
# require 'ripper'
|
@@ -20,6 +21,7 @@ require 'HDLRuby/hruby_low_with_var'
|
|
20
21
|
require 'HDLRuby/hruby_low_without_concat'
|
21
22
|
require 'HDLRuby/hruby_low_without_connection'
|
22
23
|
require 'HDLRuby/hruby_low_casts_without_expression'
|
24
|
+
require 'hruby_low_without_parinseq'
|
23
25
|
require 'HDLRuby/hruby_low_cleanup'
|
24
26
|
|
25
27
|
require 'HDLRuby/hruby_verilog.rb'
|
@@ -49,12 +51,21 @@ module HDLRuby
|
|
49
51
|
# The required files.
|
50
52
|
attr_reader :requires
|
51
53
|
|
52
|
-
# Creates a new loader for a +top_system+ system in file +
|
54
|
+
# Creates a new loader for a +top_system+ system in file +top_file_name+
|
53
55
|
# from directory +dir+ with generic parameters +params+.
|
56
|
+
#
|
57
|
+
# NOTE: +top_file+ can either be a file or a file name.
|
54
58
|
def initialize(top_system,top_file,dir,*params)
|
55
59
|
# Sets the top and the looking directory.
|
56
60
|
@top_system = top_system.to_s
|
57
|
-
@top_file
|
61
|
+
# @top_file can either be a file or a string giving the file name.
|
62
|
+
if top_file.respond_to?(:path) then
|
63
|
+
@top_file = top_file
|
64
|
+
@top_file_name = top_file.path
|
65
|
+
else
|
66
|
+
@top_file = nil
|
67
|
+
@top_file_name = top_file.to_s
|
68
|
+
end
|
58
69
|
@dir = dir.to_s
|
59
70
|
@params = params
|
60
71
|
|
@@ -81,31 +92,48 @@ module HDLRuby
|
|
81
92
|
end
|
82
93
|
|
83
94
|
# Loads a single +file+.
|
95
|
+
#
|
96
|
+
# NOTE: +file+ can either be a file or a file name.
|
84
97
|
def read(file)
|
85
98
|
# Resolve the file.
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
99
|
+
if file.respond_to?(:read) then
|
100
|
+
found = file
|
101
|
+
else
|
102
|
+
found = File.join(@dir,file)
|
103
|
+
unless File.exist?(found) then
|
104
|
+
founds = Dir.glob(@std_dirs.map do |path|
|
105
|
+
File.join(path,file)
|
106
|
+
end)
|
107
|
+
if founds.empty? then
|
108
|
+
# No standard file with this name, this is an error.
|
109
|
+
raise "Unknown required file: #{file}."
|
110
|
+
else
|
111
|
+
# A standard file is found, skip it since it does not
|
112
|
+
# need to be read.
|
113
|
+
# puts "Standard files: #{founds}"
|
114
|
+
return false
|
115
|
+
end
|
97
116
|
end
|
98
117
|
end
|
99
118
|
# Load the file.
|
100
|
-
# @texts << File.read(File.join(@dir,file) )
|
101
119
|
@texts << File.read(found)
|
102
|
-
|
103
|
-
|
120
|
+
if found.respond_to?(:path) then
|
121
|
+
@checks << Checker.new(@texts[-1],found.path)
|
122
|
+
else
|
123
|
+
@checks << Checker.new(@texts[-1])
|
124
|
+
end
|
104
125
|
return true
|
105
126
|
end
|
106
127
|
|
107
128
|
# Loads all the files from +file+.
|
108
|
-
def read_all(file =
|
129
|
+
def read_all(file = nil)
|
130
|
+
unless file then
|
131
|
+
if @top_file then
|
132
|
+
file = @top_file
|
133
|
+
else
|
134
|
+
file = @top_file_name
|
135
|
+
end
|
136
|
+
end
|
109
137
|
# puts "read_all with file=#{file}"
|
110
138
|
# Read the file
|
111
139
|
# read(file)
|
@@ -173,7 +201,7 @@ module HDLRuby
|
|
173
201
|
# Maybe it is a parse error, look for it.
|
174
202
|
bind = TOPLEVEL_BINDING.clone
|
175
203
|
eval("require 'HDLRuby'\n\nconfigure_high\n\n",bind)
|
176
|
-
eval(@texts[0],bind,@
|
204
|
+
eval(@texts[0],bind,@top_file_name,1)
|
177
205
|
# No parse error found.
|
178
206
|
raise "Cannot find a top system." unless @top_system
|
179
207
|
end
|
@@ -182,7 +210,7 @@ module HDLRuby
|
|
182
210
|
bind = TOPLEVEL_BINDING.clone
|
183
211
|
eval("require 'HDLRuby'\n\nconfigure_high\n\n",bind)
|
184
212
|
# Process it.
|
185
|
-
eval(@texts[0],bind,@
|
213
|
+
eval(@texts[0],bind,@top_file_name,1)
|
186
214
|
# Get the resulting instance
|
187
215
|
if @params.empty? then
|
188
216
|
# There is no generic parameter
|
@@ -309,15 +337,18 @@ $optparse = OptionParser.new do |opts|
|
|
309
337
|
opts.on("-D", "--debug","Set the HDLRuby debug mode") do |d|
|
310
338
|
$options[:debug] = d
|
311
339
|
end
|
340
|
+
opts.on("-T","--test","Compile the unit tests.") do |t|
|
341
|
+
$options[:test] = t
|
342
|
+
end
|
312
343
|
opts.on("-t", "--top system", "Specify the top system to process") do|t|
|
313
344
|
$options[:top] = t
|
314
345
|
end
|
315
346
|
opts.on("-p", "--param x,y,z", "Specify the generic parameters") do |p|
|
316
347
|
$options[:param] = p
|
317
348
|
end
|
318
|
-
opts.on("--
|
319
|
-
|
320
|
-
|
349
|
+
opts.on("--dump","Dump all the properties to yaml files") do |v|
|
350
|
+
$options[:dump] = v
|
351
|
+
$options[:multiple] = v
|
321
352
|
end
|
322
353
|
# opts.on_tail("-h", "--help", "Show this message") do
|
323
354
|
opts.on("-h", "--help", "Show this message") do
|
@@ -369,6 +400,19 @@ if $input == nil then
|
|
369
400
|
exit
|
370
401
|
end
|
371
402
|
|
403
|
+
if ($options[:test]) then
|
404
|
+
$top = "__test__"
|
405
|
+
# Generate the unit test file.
|
406
|
+
$test_file = Tempfile.new('tester.rb',Dir.getwd)
|
407
|
+
$test_file.write("require 'hruby_unit.rb'\nrequire_relative '#{$input}'\n\n" +
|
408
|
+
"HDLRuby::Unit.test(\"#{$top}\")\n")
|
409
|
+
# $test_file.rewind
|
410
|
+
# puts $test_file.read
|
411
|
+
$test_file.rewind
|
412
|
+
# It is the new input file.
|
413
|
+
$input = $test_file
|
414
|
+
end
|
415
|
+
|
372
416
|
# Open the output.
|
373
417
|
if $output then
|
374
418
|
if $options[:multiple] then
|
@@ -393,6 +437,12 @@ $loader = HDRLoad.new($top,$input,$options[:directory].to_s,*$params)
|
|
393
437
|
$loader.read_all
|
394
438
|
$loader.check_all
|
395
439
|
|
440
|
+
# Remove the test file if any, it is not needed any longer.
|
441
|
+
if $test_file then
|
442
|
+
$test_file.close
|
443
|
+
$test_file.unlink
|
444
|
+
end
|
445
|
+
|
396
446
|
if $options[:syntax] then
|
397
447
|
if $options[:multiple] then
|
398
448
|
raise "Multiple files generation mode not supported for syntax tree output."
|
@@ -460,6 +510,9 @@ elsif $options[:clang] then
|
|
460
510
|
# top_system = $top_system
|
461
511
|
# Preprocess the HW description for valid C generation.
|
462
512
|
$top_system.each_systemT_deep do |systemT|
|
513
|
+
# Coverts the par blocks in seq blocks to seq blocks to match
|
514
|
+
# the simulation engine.
|
515
|
+
systemT.par_in_seq2seq!
|
463
516
|
# Converts the connections to behaviors.
|
464
517
|
systemT.connections_to_behaviors!
|
465
518
|
# Break the RefConcat.
|
@@ -583,6 +636,7 @@ elsif $options[:verilog] then
|
|
583
636
|
systemT.to_global_systemTs!
|
584
637
|
# systemT.break_types!
|
585
638
|
# systemT.expand_types!
|
639
|
+
systemT.par_in_seq2seq!
|
586
640
|
systemT.initial_concat_to_timed!
|
587
641
|
systemT.with_port!
|
588
642
|
end
|
@@ -673,3 +727,31 @@ elsif $options[:vhdl] then
|
|
673
727
|
end
|
674
728
|
end
|
675
729
|
end
|
730
|
+
|
731
|
+
# Apply the post drivers if any.
|
732
|
+
Hdecorator.each_with_property(:post_driver) do |obj, value|
|
733
|
+
# Load the driver.
|
734
|
+
require_relative(value[0].to_s)
|
735
|
+
# Execute it.
|
736
|
+
send(value[1].to_sym,obj,$output)
|
737
|
+
end
|
738
|
+
|
739
|
+
# Dump the properties
|
740
|
+
if $options[:dump] then
|
741
|
+
# Decorate with the parent ids.
|
742
|
+
Hdecorator.decorate_parent_id
|
743
|
+
|
744
|
+
# Generate the directory for the properties
|
745
|
+
property_dir = $output + "/properties"
|
746
|
+
unless File.directory?(property_dir)
|
747
|
+
FileUtils.mkdir_p(property_dir)
|
748
|
+
end
|
749
|
+
|
750
|
+
# Dump to one file per key
|
751
|
+
Properties.each_key do |key|
|
752
|
+
File.open(property_dir + "/#{key}.yaml", "w") do |f|
|
753
|
+
Hdecorator.dump(key,f)
|
754
|
+
end
|
755
|
+
end
|
756
|
+
|
757
|
+
end
|