HierarchyFilesModulesSignalsTasksFunctionsHelp
Prev12345678910

reg cb_ack_event;
always @(lmcver.cb_ack) begin
  cb_ack_event = `true;
  cb_ack_event <= #(0) `false;
end

reg cb_initiator_id_event;
always @(lmcver.cb[cbinitiator_id1:cbinitiator_id2]) begin
  cb_initiator_id_event = `true;
  cb_initiator_id_event <= #(0) `false;
end


//------------
// RECEIVER --
//------------


task receiver;
reg [1:`slv_size] addr_str;
reg [1:`slv_size] data_str;
reg [`slv_size-1:0] addr_slv;
reg [`slv_size-1:0] data_slv;
reg valid_f;
integer i;
begin
  valid_f = `false;
 
if (cb_ack_event) begin
  if (driving_cb_ack_f) begin
     driving_cb_ack_f = `false;
     lmcver.cb_ack[ackack_val1:ackack_val2] <= #(0) `Release;
  end // if
end // if

if (cb_initiator_id_event && (lmcver.cb[cbinitiator_id1:cbinitiator_id2] !== `cb_release_id) && (lmcver.cb[cbinitiator_id1:cbinitiator_id2] !== id_number)) begin
  if ((lmcver.cb[cbtarget_id1:cbtarget_id2] === id_number) || (lmcver.cb[cbtarget_id1:cbtarget_id2] === `cb_brdcst_id)) begin
     if ((!(msg_level < `debug_cb))) begin
        $display("NOTE at %0t from %m", $time);
        $write("    \"Target  %0d : Receiving", id_number);
        $display("\"");
     end // if 
     busy_f = `false;

    //receive message if valid
     case (lmcver.cb[cbtransaction1:cbtransaction2])
        `cmd_trans : begin
           temp_cmd[cbfield1:cbfield2] = lmcver.cb;
           timing.to_fm_data_in(lmcver.cb[cbmsg1:cbmsg2], msg_level); //prechecks, issues syntax warnings
           temp_cmd[fmfield1:fmfield2] = timing.wk_cmd;
           if (temp_cmd[fmcode1:fmcode2] !== `null_cmd) begin
              if (temp_cmd[cbbuffer_f]) begin
                //store command in cmd_mem
                 addelement(temp_cmd[cbfield1:cbfield2],load_mem_addr,valid_f);
                 if (valid_f) begin
                    bfm_msg("Target stored buffer type command" ,`debug_cb,msg_level);
                 end
                 else begin
                    build_cmd(temp_cmd[cbmsg1:cbmsg2],"func_end"," "); // currently function name does not matter for end
                    max_cmd_mem_size = max_cmd_mem_size + 1;
                    addelement(temp_cmd[cbfield1:cbfield2],load_mem_addr,valid_f);
                 end // if
              end 
              else begin
                //verify legal execute type command
                 if (temp_cmd[fmcode1:fmcode2] !== `call_cmd) begin
                   //store command in exe_nxt_buf if empty??
                    if (exe_nxt_buf_pointer === 0) begin
                       exe_nxt_buf[exe_nxt_buf_pointer + 1] = temp_cmd;
                       exe_nxt_buf_pointer = exe_nxt_buf_pointer + 1;
                       bfm_msg("Target stored execute type command in exe_nxt_buf buffer" ,`debug_cb,msg_level);
                    end
                    else begin
                       busy_f = `true;
                      //set issued_busy_f so can broadcast a ready message
                       issued_busy_f = `true;
                       bfm_msg("Execute command buffer full, command not accepted" ,`debug_cb,msg_level);
                    end // if
                 end // if
                 else begin
                      bfm_msg("CALL_CMD Not allowed as remote/execute type command" ,`warnings,msg_level);
                 end // if
              end // if
           end // if
        end 

        `status_trans : begin
           if ((lmcver.cb[cbbuffer_avail_f]) && (lmcver.cb[cbinitiator_id1:cbinitiator_id2] === wait_on_avail_id)) begin
              wait_on_avail_f = `false;
              if ((!(msg_level < `debug_cb))) begin
                 $display("NOTE at %0t from %m", $time);
                 $write("    \"BUFFER_AVAILABLE Status received from id_number =%0d", lmcver.cb[cbinitiator_id1:cbinitiator_id2]);
                 $display("\"");
              end // if 
           end // if
           if (lmcver.cb[cbdone_f]) begin
              if ((wait_on_done_f) && (lmcver.cb[cbtag1:cbtag2] === wait_on_done_tag)) begin
                 done_f_rcvd = `true;
                 if ((!(msg_level < `debug_cb))) begin
                    $display("NOTE at %0t from %m", $time);
                    $write("    \"DONE Status received from id_number =%0d\n", lmcver.cb[cbinitiator_id1:cbinitiator_id2]);
                    $write("     Received TAG =%0d\n", lmcver.cb[cbtag1:cbtag2]);
                    $write("     WAIT_ON_TAG  =%0d", wait_on_done_tag);
                    $display("\"");
                 end // if
              end
              else begin
                 if ((!(msg_level < `debug_cb))) begin
                    $display("NOTE at %0t from %m", $time);
                    $write("    \"DONE Status received from id_number = %0d\n", lmcver.cb[cbinitiator_id1:cbinitiator_id2]);
                    $write("     Received TAG = %0d\n", lmcver.cb[cbtag1:cbtag2]);
                    $write("     WAIT_ON_TAG  = %0d", wait_on_done_tag);
                    $display("\"");
                 end // if
              end // if
           end // if
           if (lmcver.cb[cbdvalid_f]) begin
              if ((!(msg_level < `debug_cb))) begin
                  $display("NOTE at %0t from %m", $time);
                  $write("    \"DVALID Status received from id_number = %0d\n", lmcver.cb[cbinitiator_id1:cbinitiator_id2]);
                  $display("\"");
              end // if

              addr_str = lmcver.cb[cbmsg1:1126];
              data_str = lmcver.cb[1127:cbmsg2];
              addr_slv = addr_str;
              data_slv = data_str;
              return_data_addrv(addr_slv,data_slv);
           end // if
     end
     endcase

     if (!busy_f) 
        lmcver.cb_ack[ackack_val1:ackack_val2] <= #(0) `ack_rsp;
     else  
        lmcver.cb_ack[ackack_val1:ackack_val2] <= #(0) `busy_rsp;

     lmcver.cb_ack[ackinitiator_id1:ackinitiator_id2] <= #(0) lmcver.cb[cbinitiator_id1:cbinitiator_id2];
     lmcver.cb_ack[acktarget_id1:acktarget_id2] <= #(0) lmcver.cb[cbtarget_id1:cbtarget_id2];
     driving_cb_ack_f = `true;

  end // if
end // if 
end
endtask // receiver

//====================================--
//      BEGIN CONTROLLER SECTION      --
//====================================--


reg ctrl_init; initial ctrl_init = `true;
reg first_call_f; initial first_call_f = `true;

integer nest_level; initial nest_level = 0;
integer for_nest_level; initial for_nest_level = 0;
integer fh;
integer endfile;
 
reg rsp_strobe; initial rsp_strobe = 1'b0;
reg strobe_rsp_f; initial strobe_rsp_f = `false;
reg rsp_strobe_set; initial rsp_strobe_set = `false;

reg suspend_exe_f; initial suspend_exe_f = `false;
reg queue_overflow_f; initial queue_overflow_f = `false;

reg [1:1*8] curr_loop_var; initial curr_loop_var = "";
integer init_loop_val; initial init_loop_val = 0;
integer curr_loop_val; initial curr_loop_val = 0;
integer exit_val; initial exit_val = 0;
integer step_val; initial step_val = 0;
integer beg_loop_addr; initial beg_loop_addr = 0;
integer end_loop_addr; initial end_loop_addr = 0;
reg for_f; initial for_f = `false;

reg sequential_f; initial sequential_f = `false; 
integer monitor_id; initial monitor_id = 0;
 
reg wait_on_f; initial wait_on_f = `false;
integer wait_on_val; initial wait_on_val = 0;

reg wait_on_node_f; initial wait_on_node_f = `false;
reg wait_on_node_val; initial wait_on_node_val = 1'b0;
reg wait_on_node_dummy;

reg [1 : `token_size*8] exe_func_name; initial exe_func_name = "";
reg [1 : `token_size*8] curr_func_name; initial curr_func_name = "";
reg [1 : `token_size*8] seq_halt_func_name; initial seq_halt_func_name = "";
reg [1 : `max_cmd_size*8] tmp_str; initial tmp_str = "";
 
// type data_status_type is
parameter inactive = 0;
parameter active = 1;
parameter passed_val = 2;

// type data_table_element, [1:1088] = ([1:1024] name, [1025:1056] val, [1057:1088] status)
//type data_table_type is array(1 to 100) of data_table_element;

parameter addr_tbl_size = 100;
parameter var_tbl_size = 100;
integer var_tbl_counter; initial var_tbl_counter = 1;
integer addr_tbl_counter; initial addr_tbl_counter = 1;
reg [1 : 1088] var_tbl [1 : var_tbl_size];
reg [1 : 1088] addr_tbl [1 : addr_tbl_size];

initial begin
  for (i = 1; i <= addr_tbl_size; i = i + 1) begin
      var_tbl[i] = {nul_token,32'h0,32'h0};
      addr_tbl[i] = {nul_token,32'h0,32'h0};
  end // for
end

parameter stack_size = 20;
reg [31:0] returnto_stk [1 : stack_size];
integer stack_pointer; initial stack_pointer = 0;

always @(posedge (wait_on_node_dummy === 1'b1)) begin
  wait_on_node_val <= 1'b1;
end

//--------------------
// STACK PROCEDURES --
//--------------------

task push_stack;
input [31:0] stk_addr;
begin : loop_push
  if (stack_pointer > stack_size) begin
     $display("WARNING at %0t from %m", $time);
     $display("    STACK IS FULL, CANNOT PUSH MORE THAN %0d", stack_size);
     $display("    INCREASE \" stack_aize \"");
     disable loop_push;
  end // if
  
  returnto_stk[stack_pointer+1] = stk_addr;
  stack_pointer = stack_pointer + 1;  
end
endtask // push_stack

task pop_stack;
output [31:0] stk_addr;
begin : loop_pop
  if (stack_pointer < 1) begin
     $display("WARNING at %0t from %m", $time);
     $display("     STACK IS EMPTY, NOTHING TO POP OUT");
     disable loop_pop;
  end // if

  stk_addr = returnto_stk[stack_pointer];
  stack_pointer = stack_pointer - 1;
end
endtask // pop_stack

//-----------------------------
// Command Memory Procedures --
//-----------------------------


task build_cmd;
output [1:`max_cmd_size*8] ret_str;
input [1:`token_size*8] cmd_str;
input [1:`token_size*8] orig_str;
begin

  case (cmd_str)
    "func_end"		: ret_str = {"func_end","(",orig_str,")",";"};
    "declare_var"	: ret_str = {"declare_var","(",orig_str,")",";"};
    "call"		: ret_str = {"call","(",orig_str,")",";"};
    "assign_var"	: ret_str = {"assign_var","(",orig_str,")",";"};
    "func_beg"		: ret_str = {"func_beg","(",orig_str,")",";"};
  endcase

  if ((!(msg_level < `debug_cmd_mem))) begin
     $display("NOTE at %0t from %m", $time);
     $write("    \"BUILD_CMD: ret_str = %0s", ret_str);
     $display("\"");
  end // if
end
endtask // build_cmd

task set_addr_tbl_elmnt;
input [1:`token_size*8] name;
input [31:0] val;
output found;
integer i;
reg [1:`token_size*8] tmpname;
reg [1:1088] tmp_elmnt;
begin
  tmpname = name;

  begin : loop_set
    if (addr_tbl_counter > addr_tbl_size) begin
       $display("WARNING at %0t from %m", $time);
       $write("    \"SET_ADDR_TBL_ELMNT: Array \"addr_tbl\" is full, increase \"addr_tbl_size\" parameter ");
       $display("\"");
       disable loop_set;
    end // if
    for (i = 1; i <= addr_tbl_size; i = i + 1) begin
        tmp_elmnt = addr_tbl[i];
        if (tmp_elmnt[1:1024] === tmpname) begin
           if (tmp_elmnt[1057:1088] !== active) begin
              bfm_msg("SET_ADDR_TBL_ELMNT: status of element is not active" ,`warnings,msg_level);
           end // if
           tmp_elmnt[1025 : 1056] = val;
           found = `true;
           addr_tbl[i] = tmp_elmnt;
           disable loop_set;
        end
        else if (tmp_elmnt[1:1024] === nul_token) begin
          //first empty location
           tmp_elmnt[1:1024] = tmpname;
           tmp_elmnt[1025:1056] = val;
           tmp_elmnt[1057:1088] = active;
           addr_tbl[i] = tmp_elmnt;
           addr_tbl_counter = i;
           found = `false;
           disable loop_set;
        end // if
    end // loop
  end // loop_set
end
endtask // set_addr_tbl_elmnt

task get_addr_tbl_elmnt;
//-- input addr_tbl
input [1:`token_size*8] name;
inout [31:0] val;
output found;
integer i;
reg [1:`token_size*8] tmpname;
reg [1:1088] tmp_elmnt;
begin
  tmpname = name;
  found = `false;
  begin : loop_get
    for (i = 1; i <= addr_tbl_size; i = i + 1) begin
        tmp_elmnt = addr_tbl[i];
        if (tmp_elmnt[1:1024] === tmpname) begin
           if (tmp_elmnt[1057:1088] !== active) begin
              bfm_msg("GET_ADDR_TBL_ELMNT: status of element is not active" ,`warnings,msg_level);
           end // if    
           val = tmp_elmnt[1025:1056];
           found = `true;
           disable loop_get;
        end // if
    end // loop
    if ((!(msg_level < `warnings))) begin
       $display("WARNING at %0t from %m", $time);
       $write("    \"GET_ADDR_TBL_ELMNT: %0s  not found in table",tmpname);
       $display("\"");
    end // if
  end // loop_get
end
endtask // get_addr_tbl_elmnt

task set_var_tbl_elmnt;
input [1:`token_size*8] name;
input [31:0] val;
output found;
integer i;
reg [1:`token_size*8] tmpname;
reg [1:1088] tmp_elmnt;
begin
  tmpname = name;

  begin : loop_set
    if (var_tbl_counter > var_tbl_size) begin
       $display("WARNING at %0t from %m", $time);
       $write("    \"SET_VAR_TBL_ELMNT: Array \"var_tbl\" is full, increase \"var_tbl_size\" parameter ");
       $display("\"");
       disable loop_set;
    end // if
    for (i = 1; i <= var_tbl_size; i = i + 1) begin
        tmp_elmnt = var_tbl[i];
        if (tmp_elmnt[1:1024] === tmpname) begin
           if (tmp_elmnt[1057:1088] !== active) begin
              bfm_msg("SET_VAR_TBL_ELMNT: status of element is not active" ,`warnings,msg_level);
           end // if
           tmp_elmnt[1025:1056] = val;
           found = `true;
           var_tbl[i] = tmp_elmnt;
           disable loop_set;
        end
        else if (tmp_elmnt[1:1024] === nul_token) begin
          //first empty location
           tmp_elmnt[1:1024] = tmpname;
           tmp_elmnt[1025:1056] = val;
           tmp_elmnt[1057:1088] = active;
           addr_tbl[i] = tmp_elmnt;
           var_tbl_counter = i;
           found = `false;
           disable loop_set;
        end // if
    end // loop
  end // loop_set
end
endtask // set_var_tbl_elmnt

task get_var_tbl_elmnt;
//-- input var_tbl
input [1:`token_size*8] name;
inout [31:0] val;
output found;
integer i;
reg [1:`token_size*8] tmpname;
reg [1:1088] tmp_elmnt;
begin
  tmpname = name;
  found = `false;
  begin : loop_get
    for (i = 1; i <= var_tbl_size; i = i + 1) begin
        tmp_elmnt = var_tbl[i];
        if (tmp_elmnt[1:1024] === tmpname) begin
           if (tmp_elmnt[1057:1088] !== active) begin
              bfm_msg("GET_VAR_TBL_ELMNT: status of element is not active" ,`warnings,msg_level);
           end // if    
           val = tmp_elmnt[1025:1056];
           found = `true;
           disable loop_get;
        end // if
    end // loop
    if ((!(msg_level < `warnings))) begin
       $display("WARNING at %0t from %m", $time);
       $write("    \"GET_VAR_TBL_ELMNT: %0s  not found in table",tmpname);
       $display("\"");
    end // if
  end // loop_get
end
endtask // get_var_tbl_elmnt

task addelement;
//--inout cmd_mem
input [cbfield1:cbfield2] value;
output [31:0] idx;
output valid_f;
begin
  valid_f = `true;
  begin : loop_add
    // check, whether we have space in the array
    if ((cmd_mem_counter > initial_max_cmd_mem_size) && (!(msg_level < `warnings))) begin
       $display("WARNING at %0t from %m", $time);
       $display("    \"Internal Command Memory overflow while reading in command file/buffering remote commands;");
       $display("     Internal memory size may be increased using the \" initial_max_cmd_mem_size \" parameter,");
       $display("     Command file/buffer truncated, continuing simulation ...\"");
       valid_f = `false;
       disable loop_add;
    end // if
    cmd_mem[cmd_mem_counter + 1] = value;
    cmd_mem_counter = cmd_mem_counter + 1;
    idx = cmd_mem_counter;
  end // loop_add
end
endtask // addelement
  
task get_mem_cmd;
output [ctrl_store1:ctrl_store2] retcmd;
input [31:0] cmd_addr;
output valid_get_f;
reg [cbfield1:cbfield2] tmp_msg;
begin
  //get string at addr
  //convert variables(compare to names in var_tbl) to actuals of current value
  //call to_fm_data_in

  valid_get_f = `false;
  if ((cmd_addr <= max_cmd_mem_size) && (cmd_addr >= 1)) begin
     tmp_msg = cmd_mem[cmd_addr];
     if (tmp_msg[cbmsg1:cbmsg2] !== "") begin
        valid_get_f = `true;
        retcmd[cbfield1:cbfield2] = cmd_mem[cmd_addr];
        cmd_mem_hold = cmd_mem[cmd_addr];
        timing.to_fm_data_in(cmd_mem_hold[cbmsg1:cbmsg2], msg_level);
        retcmd[fmfield1:fmfield2] = timing.wk_cmd;
     end 
     else begin
        bfm_msg("Attempted read of empty location in Command Memory, return to embedded mode" ,`warnings,msg_level);
     end // if
  end
  else begin
     if ((!(msg_level < `warnings))) begin
        $display("WARNING at %0t from %m", $time);
        $write("    \"Command Memory Address Out of Range, returning to embedded mode:\n");
        $write(" Last Valid Address = %0d\n", max_cmd_mem_size);
        $write(" Attempted Address  = %0d", cmd_addr);
        $display("\"");
     end // if
  end // if
end
endtask // get_mem_cmd

function exit_cond;
input [31:0] exit_val; 
input [31:0] step_val; 
input [31:0] curr_loop_val;
begin
  if (step_val >= 0) begin
     if (curr_loop_val > exit_val) exit_cond = `true;
     else exit_cond = `false;
  end else begin
     if (curr_loop_val < exit_val) exit_cond = `true;
     else exit_cond = `false;
  end // if
end
endfunction // exit_cond

//-------------
// READ_FILE --
//-------------

 //Side effects
   //cmd_mem, load_mem_addr
   //temp_cmd, tmp_str, curr_func_name

task read_file;
integer linen;
reg [1:`token_size*8] inline;
reg [1:`token_size*8] tmp_inline;
reg [(`token_size-1)*8:0] token_1;
reg status_f;
reg error_f;
integer plitype;
integer plisize;
reg found;
reg valid_f;
begin
  linen = 0;
  inline = "";
  valid_f = `false;
  found = `false;

  if (!endfile) begin
     begin : preload
     while (!endfile) begin
           inline = "";
           tmp_inline = "";
           $lmv_fgetcmd(fh, inline, error_f);
           linen = linen + 1;
           tmp_inline = (inline >> 4);
           tmp_cb[cbmsg1:cbmsg2] = "";
           tmp_cb[cbmsg1:cbmsg2] = (inline >> 4);
           plitype = 3;
           plisize = 0;
           token_1 = "";
           $lmv_tokenize(tmp_inline, 3, 0, token_1, status_f);

           if (token_1 !== "") begin
              if (nest_level === 0) begin
                 if (token_1 === "{") begin
                    nest_level = nest_level + 1;
                 end else begin
                    //build FUNC_BEGIN command
                    build_cmd(tmp_cb[cbmsg1:cbmsg2],"func_beg",token_1);
                    addelement(tmp_cb,load_mem_addr,valid_f);
                    if (!valid_f) begin
                       disable preload; //exit preload
                    end // if
                    set_addr_tbl_elmnt(token_1,load_mem_addr,found);
                    if (found) begin
                       bfm_msg("Duplicate function names in command file:\nOnly the last declared will be used", `warnings, msg_level);
                    end // if
                    curr_func_name = token_1;
                 end // if
              end 
              else if (nest_level > 0 || sequential_f) begin
                      if (token_1 === "{") begin
                         nest_level = nest_level + 1;
                      end else if (token_1 === "}") begin
                         nest_level = nest_level - 1;
                         if (nest_level === 0) begin
                            build_cmd(tmp_cb[cbmsg1:cbmsg2],"func_end",curr_func_name);
                            if (! sequential_f) begin
                               addelement(tmp_cb,load_mem_addr,valid_f);
                               if (!valid_f) begin
                                  disable preload; //exit preload
                               end // if
                            end
                            else begin
                               timing.to_fm_data_in(tmp_cb[cbmsg1:cbmsg2], msg_level);
                               temp_cmd[fmfield1:fmfield2] = timing.wk_cmd;
                            end // if
                         end // if
                      end else if (timing.is_command(token_1)) begin
                           timing.to_fm_data_in(tmp_cb[cbmsg1:cbmsg2], msg_level);
                           temp_cmd[fmfield1:fmfield2] = timing.wk_cmd;
                           if (! sequential_f) begin
                              if (temp_cmd[fmcode1:fmcode2] !== `null_cmd) begin   //syntax okay
                                 //store string
                                 addelement(tmp_cb,load_mem_addr,valid_f);
                                 if (!valid_f) begin
                                    disable preload; //exit preload
                                 end // if
                                 if (temp_cmd[fmcode1:fmcode2] === `sequential_cmd) begin
                                    disable preload; //exit preload;
                                 end // if
                              end // if
                           end // if
                      end else begin
                           build_cmd(tmp_cb[cbmsg1:cbmsg2],"call",token_1);
                           if (! sequential_f) begin
                              addelement(tmp_cb,load_mem_addr,valid_f);
                              if (!valid_f) begin
                                    disable preload; //exit preload
                              end // if
                           end
                           else begin
                              timing.to_fm_data_in(tmp_cb[cbmsg1:cbmsg2], msg_level);
                              temp_cmd[fmfield1:fmfield2] = timing.wk_cmd;
                           end // if
                      end // if
              end // if
           end // if
           if (sequential_f) begin
              disable preload; //exit preload;
           end // if
           $lmv_endfile(fh,endfile);
     end // while
     end // preload

     if (nest_level !== 0) begin
        if (! (sequential_f || (temp_cmd[fmcode1:fmcode2] === `sequential_cmd))) begin
           bfm_msg("Syntax error in command file: Unmatched `{': Attempting to recover", `warnings, msg_level);
          //attempt to recover by adding func_end command so sim won't blow up
           max_cmd_mem_size = max_cmd_mem_size + 1;
          //build FUNC_END command
           build_cmd( tmp_cb[cbmsg1:cbmsg2],"func_end",curr_func_name);
           addelement(tmp_cb,load_mem_addr,valid_f);
        end // if
     end // if
  end // if
  if (! (sequential_f || temp_cmd[fmcode1:fmcode2] === `sequential_cmd)) begin
     if (msg_level >= `debug_cmd_mem) begin
        bfm_msg("Command Memory Loaded, Contents = ", `debug_cmd_mem, msg_level);
        begin: print_mem
          integer i;
          for (i=0; i<=cmd_mem_counter; i=i+1) begin
              cmd_mem_hold = cmd_mem[i];
              $display("%0s", cmd_mem_hold[cbmsg1:cbmsg2]);
          end // loop 
        end // print_mem
     end // if
  end // if
end
endtask // read_file

// End Read File Declarations --

//=========================
// DEALLOCATE_CTRL_QUEUE ==
//=========================

task deallocate_ctrl_queue;
input [31:0] pointer;
input [31:0] size;
integer i;
begin

  for (i = pointer; i <= size; i = i +1) begin
      ctrl_queue[i] = ctrl_queue[i+1];
  end // loop
  ctrl_queue_size = ctrl_queue_size - 1;
end
endtask // deallocate_ctrl_queue

//---------
// QUEUE --
//---------
 //Side effects
   //queue_size, ctrl_queue_end
   //new_cmd_f

task queue;
input [ctrl_store1:ctrl_store2] cmd;               // ctrl_store_data
input [31:0] which_end;                // default = end_of_queue
integer i;
begin

  if (ctrl_queue_size === 0) begin     //empty queue
     new_cmd_f = `true;
     ctrl_queue[ctrl_queue_size + 1] = cmd;  // ctrl_queue[1]
     ctrl_queue_size = ctrl_queue_size + 1;         // ctrl_queue_size = 1
  end
  else begin                             //neither _end or _beg is null
     if (which_end == end_of_queue) begin
        ctrl_queue[ctrl_queue_size + 1] = cmd;
        ctrl_queue_size = ctrl_queue_size + 1;
     end
     else begin
        for (i = ctrl_queue_size; i >= 1; i = i - 1) begin    // shift queue one location down
            ctrl_queue[i+1] = ctrl_queue[i];
        end // loop
        ctrl_queue_size = ctrl_queue_size + 1;
        ctrl_queue[1] = cmd;
     end // if
  end // if


  if (cmd[fmcode1:fmcode2] > `max_user_immed_code) begin     //must be "user_cycle" command
     num_non_immed_queued = num_non_immed_queued + 1;
  end // if
  queue_size = queue_size + 1;

  if ((!(msg_level < `debug_int))) begin
     $display("NOTE at %0t from %m", $time);
     $display("    \"QUEUE: cmd =%0d", (cmd[fmcode1:fmcode2]));
     $write("     QUEUE: queue_size = %0d", queue_size);
     $display("\"");
  end // if
end
endtask // queue

task dequeue;
input [31:0] delete_cmd_code;

//Always dequeues at least the first command in queue
//Additionally, if delete_cmd_code /= null_cmd
  //count number of occurances of delete_cmd in ctrl_queue,
  //stop counting if a multi-cycle command (which is not delete_cmd) is reached
    //if first location in queue has multi-cycle, ignore it to ensure its deletion
    //this is for case where delete_cmd_code is set to read_continue during a read_cycle
      //both the read_cycle and subsequent read_continue's should be deleted
  //then loop through dequeue loop until this number of delete_cmd's are removed
    //any zero-cycle commands between delete_cmd's will be removed
  //At this point, three conditions may exist;
    //if the queue contained only delete_cmd's and zero-cycle commands,
      //the queue will be empty except for zero-cycle commands following the last delete_cmd
    //if the queue contained a multi-cycle command (non-delete_cmd)
      //the queue will maintain zero-cycle commands between the last delete_cmd
      //and the multi-cycle command

reg [ctrl_store1:ctrl_store2] cmd_reg; //ctrl_queue_ptr
integer num_delete_cmds;
reg first_f;
integer tmp_queue_size;
integer tmp_ptr;
reg exit_search_f, exit_remove_cmd_f;
begin
  num_delete_cmds = 0;
  first_f = `true;
  tmp_queue_size = ctrl_queue_size;
  tmp_ptr = ctrl_queue_pointer;
  exit_search_f = `false;
  exit_remove_cmd_f = `false;

  if (delete_cmd_code !== `null_cmd) begin
     cmd_reg = ctrl_queue[tmp_ptr]; // ctrl_queue[1]
     num_delete_cmds = 0;
     begin: search
       while (!exit_search_f) begin
          if (tmp_queue_size === 0) begin
             exit_search_f = `true; //exit search
          end
          else if (cmd_reg[fmcode1:fmcode2] > `max_user_immed_code) begin
             if (cmd_reg[fmcode1:fmcode2] === delete_cmd_code) begin
                num_delete_cmds = num_delete_cmds + 1;
             end
             else if (! first_f) begin
                exit_search_f = `true; //exit search
             end // if
          end // if
          cmd_reg = ctrl_queue[tmp_ptr+1];
          first_f = `false;
          tmp_ptr = tmp_ptr + 1;
          tmp_queue_size = tmp_queue_size - 1;
       end // while
     end // search
  end // if

  begin: remove_cmd
    while (!exit_remove_cmd_f) begin
     ctrl_queue_hold = ctrl_queue[ctrl_queue_pointer];
     if (ctrl_queue_hold[fmcode1:fmcode2] > `max_user_immed_code) begin //must be "user_cycle" command
        num_non_immed_queued = num_non_immed_queued - 1;
        if (ctrl_queue_hold[fmcode1:fmcode2] === delete_cmd_code) begin
           num_delete_cmds = num_delete_cmds - 1;
        end // if
     end // if
     if (ctrl_queue_size !== 0) begin	//queue has at least 1 more command
        deallocate_ctrl_queue(ctrl_queue_pointer, ctrl_queue_size);
     end
     else begin					//no more commands
        deallocate_ctrl_queue(ctrl_queue_pointer, ctrl_queue_size); //also deallocates _end "dangling"
     end // if
     queue_size = queue_size - 1;
     if ((queue_size < max_ctrl_queue_size/2) && queue_overflow_f) begin
        queue_overflow_f = `false;
     end // if

     if ((!(msg_level < `debug_int))) begin
        $display("NOTE at %0t from %m", $time);
        $write("    \"DEQUEUE: removing command, queue_size = %0d", queue_size);
        $display("\"");
     end // if

     if ((ctrl_queue_size === 0) || (num_delete_cmds <= 0)) 
        exit_remove_cmd_f = `true; //exit remove_cmd when ctrl_queue_beg = null 
                                   //                     or num_delete_cmds <= 0;
       //loop will execute once if delete_cmd = null_cmd, because num_delete_cmds will be 0
    end // while
  end // remove_cmd

end
endtask // dequeue

//----------------
// CLEAR_BUSY_F --
//----------------
 //Side effects
   //dspch_data, dspch_data_f, 
   //issued_busy_f

task clear_busy_f;
begin
  if (issued_busy_f) begin
     issued_busy_f = `false;
    //signal dispatcher to broadcast ready message
     dspch_data[cbinitiator_id1:cbinitiator_id2] = id_number;
     dspch_data[cbtarget_id1:cbtarget_id2] 	 = `cb_brdcst_id;
     dspch_data[cbtransaction1:cbtransaction2]	 = `status_trans;
     dspch_data[cbdone_f]			 = `false;
     dspch_data[cbdvalid_f]			 = `false;
     dspch_data[cbbuffer_avail_f]		 = `true;
     dspch_data[cbmsg1:cbmsg2]			 = "";
     dspch_data[cbtag1:cbtag2]			 = 0;	//0 since broadcasting
    //call dispatcher to queue dspch_data for dispatching
     dspch_data_f = `true;
     dispatcher;
  end // if
end
endtask // clear_busy_f

//-------------------
// CHK_FOR_TRIGGER --
//-------------------
 //Side effects
   //exe_nxt_buf
   //dspch_data, dspch_data_f, 
   //wait_on_f,suspend_exe_f,new_cmd_f

task chk_for_trigger;
begin
  if (exe_nxt_buf_pointer !== 0) begin
     exe_nxt_buf_hold = exe_nxt_buf[exe_nxt_buf_pointer];
     if (wait_on_f) begin
        if (exe_nxt_buf_hold[fmcode1:fmcode2] ===`trigger_cmd) begin
           if ((exe_nxt_buf_hold[fmtvalue1:fmtvalue2] === wait_on_val) || (exe_nxt_buf_hold[fmtvalue1:fmtvalue2] === `blanket_tvalue)) begin
              wait_on_f = `false;
              suspend_exe_f = `false;
              new_cmd_f = `true;
           end else begin
              if ((!(msg_level < `debug_3))) begin
                 $display("NOTE at %0t from %m", $time);
                 $display("    \"TRIGGER with incorrect TVALUE received during WAIT_ON execution,");
                 $display("     deleting command from exe_nxt_buf to avoid locking model\"");
                 cb2string(exe_nxt_buf_hold[cbfield1:cbfield2]);
              end // if
           end // if
        end else begin
           if ((!(msg_level < `debug_3))) begin
              $display("NOTE at %0t from %m", $time);
              $display("    \"non-TRIGGER command received during WAIT_ON execution");
              $display("     deleting command from exe_nxt_buf to avoid locking model\"");
              cb2string(exe_nxt_buf_hold[cbfield1:cbfield2]);
           end // if
        end //if
        exe_nxt_buf_pointer = 0;
        clear_busy_f;

     end else begin
        if (exe_nxt_buf_hold[fmcode1:fmcode2] === `trigger_cmd) begin
           exe_nxt_buf_pointer = 0;
           clear_busy_f;
             bfm_msg("Model not waiting: Deleting TRIGGER from exe_nxt_buf buffer",`debug_3,msg_level);
        end // if
     end // if
  end // if
end
endtask // chk_for_trigger

//-------------------
// CHK_EXE_NXT_BUF --
//-------------------
 //Side effects
   //exe_nxt_buf, ctrl_queue
   //dspch_data, dspch_data_f, 
   //issued_busy_f, stop_queuing_f
task chk_exe_nxt_buf;
begin
  if (exe_nxt_buf_pointer !== 0) begin
     queue(exe_nxt_buf[exe_nxt_buf_pointer], beg_of_queue);
     exe_nxt_buf_pointer = 0;
  end // if
  clear_busy_f;
end
endtask // chk_exe_nxt_buf

//-------------------
// CHK_WAIT_ON_NODE --
//-------------------
 //Side effects
   //wait_on_node_f,wait_on_node_val
   //wait_on_f,suspend_exe_f,new_cmd_f

task chk_wait_on_node;
begin
  if (wait_on_node_f) begin
     if (wait_on_node_val === 1'b1) begin
        wait_on_node_f = `false;
        wait_on_f = `false;
        suspend_exe_f = `false;
        new_cmd_f = `true;
     end // if     
  end // if
end
endtask // chk_wait_on_node

//---------------
// LOAD_QUEUE  --
//---------------
 //Side effects
   //fm_rsp, rsp_strobe, strobe_rsp_f
   //cmd_mem

task load_queue;
inout [31:0] curr_mem_addr;
input top_cmd_f;  // default = `false
reg valid_get_f;
reg found;
reg new_top_cmd_f;
reg [ctrl_store1:ctrl_store2] lq_temp_cmd;  // ctrl_store_data
reg exit_queuing_f;
begin
  valid_get_f = `false;
  found = `false;
  new_top_cmd_f = top_cmd_f;
  exit_queuing_f = `false;

  bfm_msg("LOAD QUEUE" ,`debug_int,msg_level);
  if ((!new_top_cmd_f) && (!wait_on_done_f) && (!wait_on_f)) begin
     chk_exe_nxt_buf;
  end // if

begin: queuing
 while (!exit_queuing_f) begin

  if (curr_mem_addr === 0 || new_top_cmd_f) begin //load commands from embedded (top-level entity)
     if (new_top_cmd_f) begin
        new_top_cmd_f = `false;
        if (curr_mem_addr !== 0) begin
           bfm_msg("Controller not expecting command from embedded" ,`warnings,msg_level);
        end // if
        //top is sending cmd - always accept,
        //load_queue was called when fm_cmd.strobe'event
        bfm_msg("LOAD QUEUE: Receiving command from top-level" ,`debug_int,msg_level);
        
        lq_temp_cmd[cbfield1:cbfield2] = cb_field_local_cmd;
        lq_temp_cmd[fmfield1:fmfield2] = fm_cmd;
        queue(lq_temp_cmd, end_of_queue);
        if (lq_delete_cmd_code !== `null_cmd) begin
           if (lq_temp_cmd[fmcode1:fmcode2] > `max_user_immed_code) begin
              if (lq_temp_cmd[fmcode1:fmcode2] === lq_delete_cmd_code) begin
                //check for illegal condition signalled by get_nxt_cmd
                 if (lq_vfyn_f) begin
                    lq_vfyn_f = `false;
                      bfm_msg("LOAD_QUEUE: Illegal command sequence: Time-consuming statements within burst sequence;\n   Some zero-cycle commands may have been incorrectly executed", `warnings, msg_level);
                 end // if
                //command that was just queued should be deleted,
                //command was queued prior to checking so that
                //num_delete_cmds is counted properly in dequeue();
                 dequeue(lq_delete_cmd_code); //also deletes any previously queued zero-cycle commands
              end
              else begin
                 lq_delete_cmd_code = `null_cmd;
                 lq_vfyn_f = `false;
              end // if
           end // if
        end // if
        if (lq_temp_cmd[fmcode1:fmcode2] === `call_cmd) begin
           exe_call(lq_temp_cmd[fmfunction_name1:fmfunction_name2], curr_mem_addr, cmd_src);
            //if successful, changes curr_mem_addr, so signal not ready to top-level
        end // if
     end // if
     if ((num_non_immed_queued < (pipeline_depth + 1)) && (queue_size < max_ctrl_queue_size)) begin
        if (curr_mem_addr === 0) begin
          //request next command from top
           fm_rsp.ready <= #(0) `true;
            bfm_msg("LOAD QUEUE: Signalling ready to top-level" ,`debug_int,msg_level);
           strobe_rsp_f = `true;
           exit_queuing_f = `true;
        end
        else begin
           fm_rsp.ready <= #(0) `false;
            bfm_msg("LOAD QUEUE: Signalling NOT ready to top-level" ,`debug_int,msg_level);
           strobe_rsp_f = `true;
           //(no exit, load from command memory)
        end // if
     end
     else begin
        fm_rsp.ready <= #(0) `false;
         bfm_msg("LOAD QUEUE: Signalling NOT ready to top-level" ,`debug_int,msg_level);
Next12345678910
HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Thu Aug 19 12:01:57 1999
From: ../../../sparc_v8/system/lmc/rtl/pcislave_fm.v

Verilog converted to html by v2html 5.0 (written by Costas Calamvokis).Help