HDLRuby 2.4.26 → 2.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|