%#`include "<%= options[:top] %>" `timescale 1ns/1ns // 0 - Data // 1 - Reserved // // 0 - Drive // // 0 - Compare // // 0 - Force data 0 // 1 - Force data 1 // // Parameter init_drive // 0 - Initialize drive and assign to 0 // 1 - Initialize drive and assign to 1 // 2 - Don't initialize drive and assign to Z (default) // -1 - Don't initialize drive or assign. Pin will be left unknown module pin_driver(pin, sync); parameter init_drive = 2; // Which means don't drive initially, set to 0 or 1 to drive parameter pin_name = "undefined_name"; inout pin; input sync; reg error; 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; if (init_drive != -1) begin assign pin = drive ? drive_data : 1'bz; end // 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 //$display("!4![%t] Miscompare on pin %s, expected %d received %d", $time, pin_name, data[0], pin); $bridge_on_miscompare(pin_name, data[0], pin); 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, "", 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(<%= dut.rtl_pins.map { |n, p, o| "#{p.id}_o" }.join(', ') %>); % dut.rtl_pins.each do |name, pin, options| output <%= pin.id %>_o; % end reg sync = 0; % dut.rtl_pins.each do |name, pin, options| pin_driver #(<%= pin.meta[:origen_sim_init_pin_state].nil? ? '' : ".init_drive(#{pin.meta[:origen_sim_init_pin_state]}), "%>.pin_name("<%= pin.id %>")) <%= pin.id %>(.pin(<%= pin.id %>_o), .sync(sync)); % end endmodule // Placeholder for user notes. This will be an empty module if no notes were given module user_details; parameter _AVAILABLE_DETAILS_ = "<%= options[:user_details].empty? ? "" : options[:user_details].keys.join(',') %>"; % options[:user_details].each do |name, note| parameter <%= name %> = "<%= note %>"; % end endmodule // SnapshotDetails module. Just stores some traceability details into the snapshot // that can be queried by OrigenSim or viewed in the waveform viewer. module snapshot_details; // Add a parameter that lists the available parameters. OrigenSim can use this known parameter to query any others that are // added here. parameter _AVAILABLE_DETAILS_ = "ORIGEN_SIM_VERSION,COMPILATION_TIME_STAMP,COMPILATION_PATH,DEVICE_NAME,REVISION,REVISION_NOTE,TESTBENCH_VERSION,AUTHOR"; parameter ORIGEN_SIM_VERSION = "<%= OrigenSim::VERSION %>"; parameter COMPILATION_TIME_STAMP = "<%= Time.now %>"; parameter COMPILATION_PATH = "<%= Dir.pwd %>"; parameter DEVICE_NAME = "<%= options[:device_name] || 'No --device_name specified' %>"; parameter REVISION = "<%= options[:revision] || 'No --revision specified' %>"; parameter REVISION_NOTE = "<%= options[:revision_note] || 'No --revision_note specified' %>"; parameter TESTBENCH_VERSION = "<%= options[:parent_tb_version] || 'No --testbench_version specified' %>"; parameter AUTHOR = "<%= options[:author] || Origen.current_user.username %>"; user_details user_details(); endmodule module debug; reg [31:0] errors = 0; reg [15:0] marker = 0; reg [31:0] match_errors = 0; 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; snapshot_details snapshot_details(); endmodule module origen; reg finish = 0; % dut.rtl_pins.each do |name, pin, options| wire <%= pin.id %>; % end pin_drivers pins ( % dut.rtl_pins.each_with_index do |(name, pin, options), i| .<%= pin.id %>_o(<%= pin.id %>)<%= i == dut.rtl_pins.size - 1 ? '' : ',' %> % end ); // 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 % # Keep track of the primary groups seen. % seen_groups = [] % dut.rtl_pins.each_with_index do |(name, pin, options), i| % if options[:group] % unless seen_groups.include?(pin.primary_group) .<%= pin.primary_group.id %>({ % pin.primary_group.each_with_index do |pin, i| <%= pin.id %><%= i == (pin.primary_group.size - 1) ? '' : ',' %> % end })<%= (i + pin.primary_group.size) == dut.rtl_pins.size ? '' : ',' %> % seen_groups << pin.primary_group % end % else .<%= pin.rtl_name %>(<%= pin.id %>)<%= i == (dut.rtl_pins.size - 1) ? '' : ',' %> % end % end ); debug debug (); `ifdef ORIGEN_VCD initial begin $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 $finish(2); end % Array(options[:incl]).each do |f| `include "<%= "#{f}" %>" % end endmodule