%#`include "<%= options[:top] %>" `timescale 1ns/1ns // 0 - Data // 1 - Reserved // // 0 - Drive // // 0 - Compare // // 0 - Force data 0 // 1 - Force data 1 module pin_driver(error, pin, sync, match_loop); parameter init_drive = 2; // Which means don't drive initially, set to 0 or 1 to drive parameter pin_name = "undefined_name"; output reg error; inout pin; input sync; input match_loop; reg [1:0] data = 0; reg [1:0] force_data = 0; reg compare = 0; reg drive = 0; reg capture = 0; //reg [1023:0] memory = 0; reg [127:0] memory = 0; reg [127:0] memory_reversed = 0; reg [127:0] sync_memory = 0; wire drive_data = force_data[0] ? 0 : (force_data[1] ? 1 : data[0]); wire contention = drive ? (pin !== drive_data ? 1 : 0) : 0; assign pin = drive ? drive_data : 1'bz; // Debug signal to show the expected data in the waves wire expect_data = compare ? data[0] : 1'bz; always @(*) begin error = (compare && !capture) ? (pin == data[0] ? 0 : 1) : 0; end // pin compare failure logger always @(posedge error) begin if (match_loop != 1) begin $display("OrigenSim Error: miscompare on pin %s, expected %d received %d at %t", pin_name, data[0], pin, $time); end end // SMcG - needs more work, causes non-genuine fails in OrigenSim test case //// pin contention logger //always @(posedge contention) begin // $display("OrigenSim Error: contention on pin %s, tester drives %d beginning at %t", pin_name, drive_data, $time); //end always @(posedge capture) begin if (sync == 1) begin sync_memory[127:1] <= sync_memory[126:0]; sync_memory[0] <= pin; end else begin memory[127:1] <= memory[126:0]; memory[0] <= pin; memory_reversed[126:0] <= memory_reversed[127:1]; memory_reversed[127] <= pin; end end initial begin // Set the timescale to ns (-9) with 0 decimal place precision, 20 chars $timeformat(-9, 0, " ns", 20); if (init_drive == 1) begin drive = 1; data[0] = 1; end else if (init_drive == 0) begin drive = 1; data[0] = 0; end end endmodule module pin_drivers(errors, <%= dut.rtl_pins.map { |n, p, o| "#{p.id}_o" }.join(', ') %>); % dut.rtl_pins.each do |name, pin, options| output <%= pin.id %>_o; % end % dut.rtl_pins.each do |name, pin, options| wire <%= pin.id %>_err; % end output reg [31:0] errors = 0; reg sync = 0; reg [31:0] match_errors = 0; reg match_loop = 0; always @( % dut.rtl_pins.each_with_index do |(name, pin, options), i| % if i == 0 posedge <%= pin.id %>_err % else or posedge <%= pin.id %>_err % end % end ) begin if (match_loop == 1) match_errors[31:0] = match_errors[31:0] + 1; else errors[31:0] = errors[31:0] + 1; end % dut.rtl_pins.each do |name, pin, options| pin_driver #(.init_drive(<%= pin.driving? ? "#{pin.value}" : '2' %>), .pin_name("<%= pin.id %>")) <%= pin.id %>(.pin(<%= pin.id %>_o), .error(<%= pin.id %>_err), .sync(sync), .match_loop(match_loop)); % end endmodule module debug(errors); input [31:0] errors; reg [1023:0] pattern = 0; % OrigenSim::NUMBER_OF_COMMENT_LINES.times do |i| reg [1023:0] comments<%= i %> = 'h20; // Contain a space by default % end reg handshake; endmodule module origen; reg finish = 0; % dut.rtl_pins.each do |name, pin, options| wire <%= pin.id %>; % end wire [31:0] errors; pin_drivers pins ( % dut.rtl_pins.each_with_index do |(name, pin, options), i| .<%= pin.id %>_o(<%= pin.id %>), % end .errors(errors) ); // Instantiate the DUT <%= options[:top].sub(/\..*/, '') %> dut ( % dut.power_pins.each do |name, pin, options| .<%= pin.id %>(<%= pin.id %>), % end % dut.ground_pins.each do |name, pin, options| .<%= pin.id %>(<%= pin.id %>), % end % dut.rtl_pins.each_with_index do |(name, pin, options), i| % if options[:group] % if pin.group_index == 0 .<%= pin.primary_group.id %>({ % pin.primary_group.each_with_index do |pin, i| <%= pin.id %><%= i == (pin.primary_group.size - 1) ? '' : ',' %> % end })<%= i == (dut.rtl_pins.size - 1) ? '' : ',' %> % end % else .<%= pin.rtl_name %>(<%= pin.id %>)<%= i == (dut.rtl_pins.size - 1) ? '' : ',' %> % end % end ); debug debug ( .errors(errors) ); `ifdef ORIGEN_VCD initial begin //$display("********************************"); //$display("Creating origen.vcd..."); //$display("********************************"); //$dumpfile("origen.vcd"); $dumpvars(0,origen); end `endif `ifdef ORIGEN_VPD initial begin $vcdplusfile("origen.vpd"); $vcdpluson; $vcdplusmemon; end `endif `ifdef ORIGEN_FSDB initial begin $fsdbDumpfile("origen.fsdb"); $fsdbDumpvars(0, "+all"); end `endif always @(posedge finish) begin //$display("********************************"); //$display("Finishing simulation..."); //$display("********************************"); $finish(2); end % Array(options[:incl]).each do |f| `include "<%= "#{f}" %>" % end endmodule