From 97cf1a74c54fe10d50d4978d1ec2daee434958b6 Mon Sep 17 00:00:00 2001 From: pjht Date: Sun, 15 Jul 2018 16:15:29 -0500 Subject: [PATCH] VCD writer works --- lib/rcircuit.rb | 1 + lib/rcircuit/vcd.rb | 98 +++++++++++++++------------------------------ todo.txt | 2 + tst.vcd | 26 ++++++++++++ 4 files changed, 62 insertions(+), 65 deletions(-) create mode 100644 todo.txt create mode 100644 tst.vcd diff --git a/lib/rcircuit.rb b/lib/rcircuit.rb index 6c47c09..f27078e 100644 --- a/lib/rcircuit.rb +++ b/lib/rcircuit.rb @@ -6,3 +6,4 @@ require_relative "rcircuit/and.rb" require_relative "rcircuit/or.rb" require_relative "rcircuit/xor.rb" require_relative "rcircuit/adder.rb" +require_relative "rcircuit/vcd.rb" diff --git a/lib/rcircuit/vcd.rb b/lib/rcircuit/vcd.rb index 0773815..42bfcc4 100644 --- a/lib/rcircuit/vcd.rb +++ b/lib/rcircuit/vcd.rb @@ -2,91 +2,62 @@ require "set" -def create_vcd_id(index) - #VCD uses short id codes for signals. - #Generate a unique id given a numeric index, 'a' to 'z' - #then 'aa', ab',... - new_id = "" - loop do - new_id = ('a'.ord + index%26).chr + new_id - index = (index - index%26) - break if index < 1 - index = index / 26 - 1 - end - return new_id -end - -def test_vcd_id - [0, 1, 25, 26, 30, 26*26-1, 26*26, 27*26, 27*26+1].each do |i| - puts "#{i} -> #{create_vcd_id(i)}" - end -end - -#test_vcd_id() - class VCD + def initialize(filename, timescale="1ps") @fd = File.open(filename, 'w') @time=0 - @id_index = 0 - @changeset = Set.new() @timescale = timescale @portmap = {} @idmap = {} + @id = "a" write_header end - + def start - @portmap.keys.each do |portname| - port = @portmap[portname] + @fd.puts "$scope module TOP $end" + @portmap.each do |portname,port| id = @idmap[portname] - @fd.write("$var wire #{port.width} #{id} #{portname} $end\n") + @fd.puts "$var wire #{port.width} #{id} #{portname} $end" end - @fd.write("$dumpvars\n") + @fd.puts "$upscope $end" + @fd.puts "$enddefinitions $end" + @fd.puts "$dumpvars" @portmap.keys.each do |portname| write_port_state(portname) end - @fd.write("$end\n") - @fd.write("\#0\n") - return self + @fd.puts "$end" + @fd.puts "\#0" end - + def finish @fd.close end - - def attach(port, portname=nil) - if portname == nil - portname = port.to_s + + def attach(port, portname) + raise ArgumentError.new("Duplicate port name '#{portname}'") if @portmap.has_key?(portname) + if port.width > 1 + portname="#{portname}[0:#{port.width-1}]" end - raise RunTimeError.new("Duplicate port name '#{portname}'") if @portmap.has_key?(portname) - @idmap[portname] = create_vcd_id(@id_index) - @id_index += 1 + @idmap[portname] = @id + @id=@id.next() @portmap[portname] = port port.add_callback do |value| - @changeset.add(portname) - end - return self - end - - def advance(timesteps) - @time += timesteps - @fd.write("\##{@time.to_s}\n") - return self - end - - def write - #write out any changes and clear the changed set - @changeset.each do |portname| write_port_state(portname) end - @changeset.clear end - + + def advance(timesteps) + @time += timesteps + @fd.puts "\##{@time.to_s}" + end + + private + def write_header - @fd.write("$date\n#{Time.now.asctime}\n$end\n") - @fd.write("$version\nRCircuit VCD Generator Version 0.0\n$end\n") - @fd.write("$timescale #{@timescale} $end\n") + @fd.puts "$version\nRCircuit VCD Generator Version 0.0\n$end" + @fd.puts "$date\n#{Time.now.asctime}\n$end" + @fd.puts "$timescale #{@timescale} $end" end def write_port_state(portname) @@ -95,12 +66,9 @@ class VCD if port.width == 1 state = port.val.to_s else - state = "b#{port.val.to_s(2)} " #include a space + state = "b#{port.val.to_s(2)} "#include a space end - @fd.write(state + @idmap[portname] + "\n") + @fd.puts state+@idmap[portname] end - -end - - \ No newline at end of file +end diff --git a/todo.txt b/todo.txt new file mode 100644 index 0000000..2c53019 --- /dev/null +++ b/todo.txt @@ -0,0 +1,2 @@ +Must document VCD and Adder +Must add tests for VCD and Device diff --git a/tst.vcd b/tst.vcd new file mode 100644 index 0000000..0dea325 --- /dev/null +++ b/tst.vcd @@ -0,0 +1,26 @@ +$version +RCircuit VCD Generator Version 0.0 +$end +$date +Thu Jul 12 07:57:29 2018 +$end +$timescale 1ps $end +$scope module TOP $end +$var wire 8 a a[0:7] $end +$var wire 8 b b[0:7] $end +$upscope $end +$enddefinitions $end +$dumpvars +b0 a +b0 b +$end +#0 +b1000 a +b1010 b +#1 +b10000 a +b11101 b +#2 +b0 a +b0 b +#3