Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Constants
- N = 32 #number of mask gates we are going to insert
- TB = "ben_tb.v" #test bench file
- CKT = "ben_scan.v" #circuit file
- CPR = "critpaths.report"
- CLKTOD = /^(?<dstart>DFF\_\d+\_Q\_reg)\/CLK\s\(SDFFX1\).*(?<dend>DFF\_\d+\_Q\_reg)\/D\s\(SDFFX1\)/ #for finding paths in critpaths.report
- KEY = ["0"]*N
- TRN = ["0"]*N
- #read in the first file
- ckt = File.read(CKT).split(/\n/) #read in circuit
- #flatten the verilog so that it is easier to work with
- a = "\n" #initialize, don't know why inject wasn't working
- ckt.each do |b|
- if (a[-1] != "\n") #if last line wasn't complete
- a.concat(b.sub(/^\s*/,"")) #add this line with trailing whitespace removed
- else #if last line is already complete
- a.concat(b) #add this line just as it was before
- end
- (b =~ /\;$/) ? a.concat("\n") : nil #if command terminated, add newline
- end
- #we now have a as a flatter version of the input file.
- a = a.split(/\n/)
- #we need to add key and trn signature/inputs to the verilog file.
- a = a.map{|l| (l =~ /^\s*module/) ? (l.sub(" );",(0...N).inject(""){|a,b| a.concat(", key#{b}, trn#{b}")}.concat(");"))) : l}
- a = a.map{|l| (l =~ /^\s*input/) ? (l.sub(";",(0...N).inject(""){|a,b| a.concat(", key#{b}, trn#{b}")}.concat(";"))) : l}
- #need to find the paths that we are going to insert the xor gates onto
- paths = File.read('critpaths.report').split(/\n/).reverse.map{|e| (e.to_s =~ CLKTOD) ? $2 : nil}.select{|e| e != nil}.take(N) #takes lowest 32 paths matching regex
- gates = paths.map{|e| a.select{|f| f =~ Regexp.new(Regexp.escape(e))}} #finds the gates terminating those paths
- nets = gates.map{|e| (e.to_s =~ /\.D\((?<gate>.*?)\)/) ? $1 : nil} #finds the nets feeding into the gates terminating those paths
- #create the masks
- (0...N).each do |e|
- s = " XOR3X1 MSK#{e.to_s} ( .IN1(key#{e.to_s}), .IN2(trn#{e.to_s}), .IN3(#{nets[e]}), .Q(xgt#{e.to_s}));"
- a.insert(-2,s)
- a.map!{|f| (f =~ Regexp.new(Regexp.escape(paths[e]))) ? (f=f.sub(nets[e],"xgt#{e.to_s}")) : f}
- end
- #write the file
- a = a.inject(""){|a,l| a.concat(l.concat("\n"))} #compresses a back into a single string
- File.open("scan_edit.v",'w+') {|f| f.write(a)}
- #read in testbench, edit file. a little hackier than above but should usually still work.
- tbn = File.read(TB).split(/\n/)
- ins = (0...N).reduce(""){|f,g| f.concat(",\n .key#{g}(1'b#{KEY[g]}),\n .trn#{g}(1'b#{TRN[g]})")}
- tbn.map!{|e| (e =~ /\.test\_se\(test_se\)/) ? (e.insert(-6,ins)): e}
- tbn = tbn.reduce(""){|a,l| a.concat(l.concat("\n"))}
- File.open("tb_edit.v",'w+') {|f| f.write(tbn)}
Add Comment
Please, Sign In to add comment