addelement(tmp_cb,load_mem_addr,valid_f);
end // if
end
`func_beg_cmd : begin
//sets local variables value to approp. tmp_var, and sets status to "passed_val"
//currently using only global variables, so this command is non-functional
end
`func_end_cmd : begin
//--return value, set status of local vars, return to parent addr
//--currently using only global variables, so this command only returns toparent addr
//!!8.0.burst - add comment, remove exe_func_end
//command is executed when queued
//!! exe_func_end(cmd[fmfunction_name1:fmfunction_name2], curr_mem_addr, cmd_src);
end
`sequential_cmd : begin
end
`stop_sim_cmd : begin
$display("======================================================================");
$display("NOTE at time %t from %m",$time);
$display(" \" stop_sim command issued, simulation stopped immediately \"");
$display("======================================================================");
$finish;
end
`wait_on_node_cmd : begin
wait_on_node_dummy = 1'b0;
$lmv_wait_on(cmd[fmnode_name1:fmnode_name2],cmd[fmnode_value1:fmnode_value2],cmd[fmnode_mask1:fmnode_mask2],wait_on_node_dummy,ret_stat);
if (!ret_stat) begin // Change ret_stat non_zero, no_wait, event already occurred
wait_on_node_val = 1'b0;
wait_on_f = `true;
wait_on_node_f = `true;
end // if
end
default : begin
if ((!(msg_level < `warnings))) begin
$display("WARNING at %0t from %m", $time);
$write(" \"EXE_CTRL_IMMED: Received invalid command,code=%0s",cmd2string(cmd[fmcode1:fmcode2]));
$display("\"");
end // if
end
endcase
end
endtask // exe_ctrl_immed
//---------------
// CONTROLLER --
//---------------
//Operation
//this procedure performs controller operations other than:
// get_nxt_cmd, excpt_detected, return_data
//Side Effects
//ctrl_init
//curr_mem_addr
//rsp_strobe,strobe_rsp_f
//done_f_rcvd, wait_on_done_f, new_cmd_f
// procedure get_nxt_cmd;
task controller;
begin
// if (msg_level >= `debug_3) begin
// $display("NOTE at %0t from %m",$time);
// $display(" pcimaster_fm.v controller");
// end // if
rsp_strobe_set = `false;
if (ctrl_init) begin
ctrl_init = `false;
load_queue(curr_mem_addr, `false);
if (strobe_rsp_f) begin
strobe_rsp_f = `false;
if (rsp_strobe_set != `true) begin
rsp_strobe_set = `true;
rsp_strobe = ~rsp_strobe;
fm_rsp.strobe <= #(0) rsp_strobe;
end // if
end // if
end // if
if (fm_cmd_strobe_event) begin
load_queue(curr_mem_addr,`true);
if (strobe_rsp_f) begin
strobe_rsp_f = `false;
if (rsp_strobe_set != `true) begin
rsp_strobe_set = `true;
rsp_strobe = ~rsp_strobe;
fm_rsp.strobe <= #(0) rsp_strobe;
end // if
end // if
end // if
if (done_f_rcvd) begin
done_f_rcvd = `false;
wait_on_done_f = `false;
suspend_exe_f = `false;
new_cmd_f = `true;
end // if
chk_for_trigger;
chk_wait_on_node;
if ((ctrl_queue_size === 0) && (! wait_on_done_f)) begin // empty and not waiting
if (exe_nxt_buf_pointer !== 0) begin
new_cmd_f = `true;
//only set flag here, queue using exe_nxt_buf data when get_nxt_cmd called
end // if
end // if
end
endtask // controller
//The following controller routines are called by the executer
//---------------
// GET_NXT_CMD --
//---------------
//Side Effects
//cmd_queue, ctrl_queue, num_non_immed_queued, queue_size
//new_cmd_f
//curr_cmd
task get_nxt_cmd;
integer i;
reg exit_f;
begin
exit_f = `false;
//peforms necessary end-of-command operations
//dispatches status,return data, and monitor commands
//removes completed command from queue
//checks the exe_nxt_buf buffer for a command
//loads queue as necessary
//executes next command if it is an immediate command,
//else exits get_nxt_cmd after updating curr_cmd
bfm_msg("GET_NXT_CMD" ,`debug_int,msg_level);
begin : get_nxt
while (!exit_f) begin
//!!8.0.burst begin - add "if"/body
if ((!suspend_exe_f) && (ctrl_queue_size !== 0) &&
(lq_delete_cmd_code !== `null_cmd) && (num_non_immed_queued === 0)) begin
//time-consuming statements are among burst and queue contains zero-cycle commands
//which may be incorrectly executed
//set flag so load_queue can verify/warn
lq_vfyn_f = `true;
end // if
//!!8.0.burst end - add "if"/body
//!!8.0.burst - change "if" condition and comment
if ((!new_cmd_f) && (!suspend_exe_f) && (ctrl_queue_size !== 0)) begin
//This section of code is normally entered after execution of each command
//purpose is to perform end-of-command operations and delete command from queue
//not new_cmd_f ensures that the first command in the queue has been executed
//not suspende_exe_f ensures that command execution has not been suspended
// this could be due to either a wait_on command,
// a remote dispatched with notify_f set true or
// wait_on_node command
//ctrl_queue_size !== 0 ensures that the queue is not empty
//perform end-of-command operations
done_chks(ctrl_queue[ctrl_queue_pointer]);
//dispatches status,return data, and monitor commands
suspend_exe_f = (wait_on_f | wait_on_done_f);
//!!8.0.burst - change comment
//dequeue command(s)
//current command always deleted
//modeler may specify additional commands to be deleted through delete_cmd_code variable
//if delete_cmd_code != `null_cmd, all subsequent delete_cmd's are removed until a different
//multi-cycle command is reached. Any zero-cycle commands between delete_cmd's are removed
//!!8.0.burst begin - replace code
//!! ctrl_queue_hold = ctrl_queue[ctrl_queue_pointer];
//!! if (ctrl_queue_hold[fmcode1:fmcode2] > `max_user_immed_code) begin //must be "user_cycle" command
//!! // special for pci
//!! if ((ctrl_queue_hold[fmcode1:fmcode2] !== `read_continue_cmd) && (ctrl_queue_hold[fmcode1:fmcode2] !== `write_continue_cmd)) begin
//!! num_non_immed_queued = num_non_immed_queued - 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(" \"GET_NXT_CMD: Dequeue, queue_size = %0d", queue_size);
//!! $display("\"");
//!! end // if
//!! begin new
dequeue(delete_cmd_code);
if ((num_non_immed_queued === 0) && (delete_cmd_code !== `null_cmd)) begin
//load_queue should continue to delete incoming delete_cmd's
if (lq_delete_cmd_code !== `null_cmd) begin
//modeler has set delete_cmd again before controller reset lq_delete_cmd_code
//modeler may have called get_nxt_cmd multiple times in same time iteration
//(along with setting delete_cmd_code each time)
bfm_msg("Model has overlapping requests to delete burst sequences;\n New request only is serviced", `warnings, msg_level);
end // if
lq_delete_cmd_code = delete_cmd_code;
if ((ctrl_queue_size !== 0) && (num_non_immed_queued === 0)) begin
//time-consuming statement in embedded command sequence
//residual zero-cycle's in queue will be executed
//if next multi-cycle received from top is delete_cmd, a warning is issued from load_queue
//set flag here to notify load_queue of potential illegal condition
lq_vfyn_f = `true;
end
else begin
lq_vfyn_f = `false; //ensures that for external file mode, flag is reset
end // if
end // if
delete_cmd_code = `null_cmd;
//!! end new
//!!8.0.burst end - replace code
end // if
//fill queue if necessary
load_queue(curr_mem_addr, `false);
//execute next command if immediate else exit procedure
ctrl_queue_hold = ctrl_queue[ctrl_queue_pointer];
if ((ctrl_queue_size !== 0) && (! wait_on_done_f) && (!suspend_exe_f)) begin
if (new_cmd_f) begin
new_cmd_f = `false;
end // if
if (ctrl_queue_hold[fmcode1:fmcode2] <= `max_ctrl_immed_code) begin
exe_ctrl_immed(ctrl_queue_hold); //in controller section
end else if (ctrl_queue_hold[fmcode1:fmcode2] <= `max_auto_immed_code) begin
exe_auto_immed(ctrl_queue_hold[fmfield1:fmfield2]); //in tool-gen m.s. section
end else if (ctrl_queue_hold[fmcode1:fmcode2] <= `max_user_immed_code) begin
exe_user_immed(ctrl_queue_hold[fmfield1:fmfield2]); //in executer section
end
else begin
//load pipeline commands
temp_cmd_ptr = ctrl_queue_pointer;
for (i = 0; i <= pipeline_depth-1; i = i + 1) begin
if (ctrl_queue_size !== 0) begin
ctrl_queue_hold = ctrl_queue[temp_cmd_ptr];
cmd_queue[i] = ctrl_queue_hold[fmfield1:fmfield2];
temp_cmd_ptr = temp_cmd_ptr + 1;
end
else begin
cmd_queue[i] = timing.fm_data_in_init;
//!!8.0 change - used ^^^^^^^ fm_data_in_init in timing
end // if
end // loop
//copy cmd_queue(0) to curr_cmd
curr_cmd = cmd_queue[0];
exit_f = `true;
end // if
end
else begin //empty
for (i = 0; i <= pipeline_depth-1; i = i + 1) begin
cmd_queue[i] = timing.fm_data_in_init;
//!!8.0 change - used ^^^^^^^ fm_data_in_init in timing
end // loop
curr_cmd = cmd_queue[0];
exit_f = `true;
end // if
end // while
end // get_nxt
if (strobe_rsp_f) begin
strobe_rsp_f = `false;
if (rsp_strobe_set != `true) begin
rsp_strobe_set = `true;
rsp_strobe = ~rsp_strobe;
fm_rsp.strobe <= #(0) rsp_strobe;
end // if
end // if
if ((!(msg_level < `debug_3))) begin
$display("NOTE at %0t from %m", $time);
$write(" \"GET_NXT_CMD: Exiting, new command =%0s", cmd2string(curr_cmd[incode1:incode2]));
$display("\"");
end // if
// $write(" \"curr_cmd[incode1:incode2] = %0d \n", curr_cmd[incode1:incode2]);
// $write(" \"curr_cmd[inwtye1:inwtype22] = %0d \n", curr_cmd[inwtype1:inwtype2]);
// $write(" \"curr_cmd[inaddr1:inaddr2] = %h \n", curr_cmd[inaddr1:inaddr2]);
// $write(" \"curr_cmd[intc1:intc2] = %0d \n", curr_cmd[intc1:intc2]);
// $write(" \"curr_cmd[inbyten1:inbyten2] = %h \n", curr_cmd[inbyten1:inbyten2]);
// $write(" \"curr_cmd[indata1:indata2] = %h \n", curr_cmd[indata1:indata2]);
// $write(" \"curr_cmd[indelay1:indelay2] = %0d \n", curr_cmd[indelay1:indelay2]);
// $write(" \"curr_cmd[inlock1:inlock2] = %0d \n", curr_cmd[inlock1:inlock2]);
// $display("\"");
end
endtask // get_nxt_cmd
//-----------------
// GET_NON_IMMED --
//-----------------
task get_non_immed;
input [31:0] num;
output [fm_data_in1:fm_data_in2] cmd;
reg [ctrl_store1:ctrl_store2] cmd_ptr;
integer num_non_immed;
integer tmp_ctr;
integer tmp_queue_size;
reg immed_exit;
begin
num_non_immed = 0;
tmp_queue_size = ctrl_queue_size;
tmp_ctr = 1;
immed_exit = `false;
cmd_ptr = ctrl_queue[ctrl_queue_pointer]; // ctrl_queue[1]
begin : loop_search
while(!immed_exit) begin
if (tmp_queue_size === 0) begin
cmd[incode1:incode2] = `idle_cmd;
cmd[incycles1:incycles2] = 1;
immed_exit = `true; // return
end
else if (cmd_ptr[fmcode1:fmcode2] > `max_user_immed_code) begin
num_non_immed = num_non_immed + 1;
if (num_non_immed === num) begin
cmd = cmd_ptr[fmfield1:fmfield2];
immed_exit = `true; // return
end // if
end // if
else if ((cmd_ptr[fmcode1:fmcode2] === `wait_on_cmd)
|| ((cmd_ptr[fmcode1:fmcode2] === `remote_cmd)
&& cmd_ptr[fmnotify_f])
|| (cmd_ptr[fmcode1:fmcode2] === `wait_on_node_cmd)) begin
cmd[incode1:incode2] = `idle_cmd;
cmd[incycles1:incycles2] = 1;
immed_exit = `true; //return
end // if
cmd_ptr = ctrl_queue[tmp_ctr + 1];
tmp_ctr = tmp_ctr + 1;
tmp_queue_size = tmp_queue_size - 1;
end // while
end // loop_search
end
endtask // get_non_immed
//---------------
// RETURN_DATA --
//---------------
//Side Effects
//ret_data_slv
//dvalid_f
task return_data_b;
input rdata;
begin
if ((!(msg_level < `debug_3))) begin
$display("NOTE at %0t from %m", $time);
$write(" \"RETURN_DATA: data = %H", rdata);
$display("\"");
end // if
ret_data_mask = 64'hffffffffffffffe;
ret_data_slv = 64'hxxxxxxxxxxxxxxxx;
ret_data_slv[0] = rdata;
dvalid_f = `true;
end
endtask // return_data_b
task return_data_v;
input [63:0] rdata;
begin
if ((!(msg_level < `debug_3))) begin
$display("NOTE at %0t from %m", $time);
$write(" \"RETURN_DATA: data = %H", rdata);
$display("\"");
end // if
ret_data_mask = 64'h0;
ret_data_slv = rdata;
dvalid_f = `true;
end
endtask // return_data_v
task return_data_addrb;
input [63:0] addr;
input rdata;
begin
if ((!(msg_level < `debug_3))) begin
$display("NOTE at %0t from %m", $time);
$write(" \"RETURN_DATA:\n");
$write(" address = %H\n", addr);
$write(" data = %H", rdata);
$display("\"");
end // if
ret_addr_slv = addr;
ret_data_mask = 64'hffffffffffffffe;
ret_data_slv = 64'hxxxxxxxxxxxxxxxx;
ret_data_slv[0] = rdata;
dvalid_f = `true;
end
endtask // return_data_addrb
task return_data_addrv;
input [63:0] addr;
input [63:0] rdata;
begin
if ((!(msg_level < `debug_3))) begin
$display("NOTE at %0t from %m", $time);
$write(" \"RETURN_DATA:\n");
$write(" address = %H\n", addr);
$write(" data = %H", rdata);
$display("\"");
end // if
ret_addr_slv = addr;
ret_data_mask = 64'h0;
ret_data_slv = rdata;
dvalid_f = `true;
end
endtask // return_data_addrv
//====================================--
// END CONTROLLER SECTION --
//====================================--
//====================================--
// BEGIN DISPATCHER SECTION --
//====================================--
//-----------------------------
//Dispatcher Declarations -----
//-----------------------------
reg [cbfield1:cbfield2] dspch_queue
[0 : `dspch_queue_page_size-1]; // control_bus_type
reg [cbfield1:cbfield2] dspch_queue_hold
; // control_bus_type
integer in_dspch_q_ptr
; initial in_dspch_q_ptr
= 0; // first empty location
integer out_dspch_q_ptr
; initial out_dspch_q_ptr
= 0; // location to be output
reg dspch_q_empty
; initial dspch_q_empty
= `true;
integer dspch_tag
; initial dspch_tag
= 0;
integer active_target_id
; initial active_target_id
= 0;
integer ack_srch_ct
; initial ack_srch_ct
= 0; //num.of attempts to find cb_ack
reg check_cb_ack_f
; initial check_cb_ack_f
= `false;
reg wait_on_ack_f
; initial wait_on_ack_f
= `true;
reg released_cb_f
; initial released_cb_f
= `true;
integer wait_on_avail_t
; initial wait_on_avail_t
= 0 * `time_scale_multiplier;
reg driving_cb_f
; initial driving_cb_f
= `false;
reg check_cb_ack_event
;
always @(check_cb_ack) begin
check_cb_ack_event = `true;
check_cb_ack_event <= #(0) `false;
end
//---------------------------
// Dispatcher Procedures ----
//---------------------------
task queue_dspch;
input [cbfield1:cbfield2] dspch_data; // control_bus_type
begin : dspch_loop
if (in_dspch_q_ptr >= `dspch_queue_page_size) begin
if (out_dspch_q_ptr !== 0) begin
in_dspch_q_ptr = 0;
end
else begin
bfm_msg("Dispatcher Queue Overflow: Dispatch data not queued for output" ,`warnings,msg_level);
disable dspch_loop; // return
end // if
end // if
if ((!(msg_level < `debug_3))) begin
$display("NOTE at %0t from %m", $time);
$write(" \"QUEUE_DSPCH: Initiator %0d", id_number);
$write(" : Storing data to be dispatched, location = %0d", in_dspch_q_ptr);
$display("\"");
end // if
dspch_queue[in_dspch_q_ptr] = dspch_data;
in_dspch_q_ptr = in_dspch_q_ptr + 1;
end // dspch_loop
endtask // queue_dspch
task dequeue_dspch;
begin
if (out_dspch_q_ptr !== in_dspch_q_ptr) begin
out_dspch_q_ptr = out_dspch_q_ptr + 1;
if (out_dspch_q_ptr == `dspch_queue_page_size) begin
out_dspch_q_ptr = 0;
if (in_dspch_q_ptr === `dspch_queue_page_size) begin
//in ptr hasn't been reset, but queue is empty
in_dspch_q_ptr = 0;
end // if
end // if
end
else begin
bfm_msg("DEQUEUE_DSPCH: Error in dispatcher's queue" ,`warnings,msg_level);
end // if
end
endtask // dequeue_dspch
//---------------
// Dispatcher --
//---------------
task dispatcher;
integer temp_time;
reg [cbfield1:cbfield2] t_dspch_queue;
begin
begin : loop_dispatcher
//queue dispatch data if necessary
if (dspch_data_f) begin
dspch_data_f = `false;
if ((dspch_data[cbtransaction1:cbtransaction2] === `cmd_trans) && (dspch_data[cbtag1:cbtag2] === 0)) begin
dspch_data[cbtag1:cbtag2] = dspch_tag;
dspch_tag = dspch_tag + 1;
end // if
queue_dspch(dspch_data);
disable loop_dispatcher; // return
end // if
//monitor Control Bus activity
if (cb_initiator_id_event) begin
if ((lmcver.cb[cbinitiator_id1:cbinitiator_id2] === id_number) && (driving_cb_f)) begin
//this model just became owner of Control Bus, release now so message is valid for 1 tick
driving_cb_f = `false;
lmcver.free_bus(id_number);
lmcver.cb[cbinitiator_id1:cbinitiator_id2] <= #(0) `cb_release_id;
check_cb_ack_f = `true;
active_target_id = lmcver.cb[cbtarget_id1:cbtarget_id2];
check_cb_ack <= #(0) ~check_cb_ack;
if ((!(msg_level < `debug_cb))) begin
$display("NOTE at %0t from %m", $time);
$write(" \"DISPATCHER: Initiator %0d: Message on CB, Release CB",id_number);
$display("\"");
end // if
end // if
end // if
if ((check_cb_ack_event) && (check_cb_ack_f)) begin
t_dspch_queue = dspch_queue[out_dspch_q_ptr];
if ((!(msg_level < `debug_cb))) begin
$display("NOTE at %0t from %m", $time);
$write(" \"DISPATCHER: Initiator %0d: Check # %0d", id_number, (ack_srch_ct+1));
$write(" for response to message w/ TAG = %0d\n", t_dspch_queue[cbtag1:cbtag2]);
$display(" initiator_id = %0d", lmcver.cb_ack[ackinitiator_id1:ackinitiator_id2]);
$display(" target_id = %0d", lmcver.cb_ack[acktarget_id1:acktarget_id2]);
$write(" ack_val = %0s", cbackval2string(lmcver.cb_ack[ackack_val1:ackack_val2]));
$display("\"");
end // if
//check response
if (((lmcver.cb_ack[ackinitiator_id1:ackinitiator_id2] === id_number) && (lmcver.cb_ack[acktarget_id1:acktarget_id2] === active_target_id))
|| (active_target_id === `cb_brdcst_id)) begin
check_cb_ack_f = `false;
ack_srch_ct = 0;
//valid response (assumed for broadcast)
if ((lmcver.cb_ack[ackack_val1:ackack_val2] === `ack_rsp) || (active_target_id === `cb_brdcst_id)) begin
//message accepted (assumed for broadcast)
dequeue_dspch;
bfm_msg("Message was received by Target(s)" ,`debug_cb,msg_level);
end else if (lmcver.cb_ack[ackack_val1:ackack_val2] === `busy_rsp) begin
//save message for resending
wait_on_avail_f = `true;
dspch_queue_hold = dspch_queue[out_dspch_q_ptr];
wait_on_avail_id = dspch_queue_hold[cbtarget_id1:cbtarget_id2];
wait_on_avail_t = $time;
bfm_msg("Target responded with BUSY" ,`debug_cb,msg_level);
end else if (lmcver.cb_ack[ackack_val1:ackack_val2] === `unknown) begin
//error, for bus conflict, resolution outputs id's = 0, so target must have output `unknown'
if ((!(msg_level < `debug_cb))) begin
$display("WARNING at %0t from %m", $time);
$write(" \"DISPATCHER: Initiator %0d :Received UNKNOWN acknowledge",id_number);
$display("\"");
end // if
end else if (lmcver.cb_ack[ackack_val1:ackack_val2] === `Release) begin
//not a possible comb. due to resolution (if ack_val = release, id's = 0)
if ((!(msg_level < `debug_cb))) begin
$display("WARNING at %0t from %m", $time);
$write(" \"DISPATCHER: Initiator %0d :Received RELEASE acknowledge",id_number);
$display("\"");
end // if
end // if
end
else begin
//improper response, ignore and keep looking for ack upto max_ack_srch
if (ack_srch_ct >= (`max_ack_srch-1)) begin
if ((!(msg_level < `debug_cb))) begin
$display("WARNING at %0t from %m", $time);
$write(" \"DISPATCHER: CB_ACK check timeout expired, No valid response to message:\n");
$write(" Message deleted from dispatch queue");
$display("\"");
end // if
check_cb_ack_f = `false;
ack_srch_ct = 0;
dequeue_dspch;
end else begin
ack_srch_ct = ack_srch_ct + 1;
check_cb_ack <= #(0) ~check_cb_ack;
end // if
end // if
end // if
temp_time = ($time - wait_on_avail_t);
if ((wait_on_avail_f) && (temp_time >= `max_wait_on_avail_t)) begin
if ((!(msg_level < `debug_cb))) begin
$display("WARNING at %0t from %m", $time);
$write(" \"DISPATCHER: Wait_on_avail timeout expired, Target not available for message:\n");
$write(" Message deleted from dispatch queue");
$display("\"");
end // if
wait_on_avail_f = `false;
dequeue_dspch;
end // if
if (in_dspch_q_ptr === out_dspch_q_ptr) dspch_q_empty = `true;
else dspch_q_empty = `false;
if (ack_srch_ct !== 0) wait_on_ack_f = `true;
else wait_on_ack_f = `false;
//output dispatch data if possible
if ((!dspch_q_empty) && (lmcver.cb[cbinitiator_id1:cbinitiator_id2] === `cb_release_id) && (!driving_cb_f)
&& (!wait_on_avail_f) && (!wait_on_ack_f) && (!check_cb_ack_f)) begin
//attempt dispatch
driving_cb_f = `true;
lmcver.request_bus(id_number);
lmcver.cb[cbinitiator_id1:cbinitiator_id2] = lmcver.winner_id;
if (lmcver.cb[cbinitiator_id1:cbinitiator_id2] === id_number) begin
//?? lmcver.cb <= #(0) dspch_queue[out_dspch_q_ptr];
lmcver.cb = dspch_queue[out_dspch_q_ptr];
end else begin
driving_cb_f = `false;
end // if
if ((!(msg_level < `debug_cb))) begin
$display("WARNING at %0t from %m", $time);
$write(" \"Initiator %0d: Driving cb with dispatch queue location =%0d",id_number,out_dspch_q_ptr);
$display("\"");
cb2string(dspch_queue[out_dspch_q_ptr]);
end // if
end // if
end // loop_dispatcher
end
endtask // dispatcher
//====================================--
// END DISPATCHER SECTION --
//====================================--
//====================================--
// BEGIN EXECUTER SECTION --
//====================================--
parameter cmd_queue_depth = pipeline_depth;
reg init
; initial init
= `true;
//**--**--**--**--**--**--**--**-- Executer Declarations USER CODE BEGIN
//-------------------------------
//-------------------------------
// Enter user variables here --
//-------------------------------
//-------------------------------
//type cmd_states
parameter cmd_rdy = 0;
parameter data_rd = 1;
parameter data_wr = 2;
parameter ddelay = 3;
parameter cmd_dly = 4;
parameter disabled = 5;
//type step_states
parameter counting = 0;
parameter waiting = 1;
parameter deasserting = 2;
//type bus_machine_states
parameter sidle = 0;
parameter saddr = 1;
parameter sm_data = 2;
parameter sturn_ar = 3;
parameter ss_tar = 4;
parameter sdr_bus = 5;
//type lock_machine_states
parameter free = 0;
parameter busy = 1;
//type command_type
parameter write = 0;
parameter read = 1;
//type dev_to_states
//parameter counting = 0;
parameter idle = 100;
parameter timed_out = 2;
reg latched_lock_a
; initial latched_lock_a
= 1'bx; //
integer latched_bstate
/*: bus_machine_states*/; //
reg latched_comp
; initial latched_comp
= 1'bx; //
integer dtstate
/*: dev_to_states*/ ; initial dtstate
= idle;
integer cycle_command
/*: command_type*/ ; initial cycle_command
= read;
integer last_cycle_command
/*: command_type*/ ; initial last_cycle_command
= read;
integer command
/*: command_type*/ ; initial command
= read;
integer commd
/*: command_type*/ ; initial commd
= read;
integer lstate
/*: lock_machine_states*/ ; initial lstate
= free;
integer bstate
/*: bus_machine_states*/ ; initial bstate
= sidle;
integer saved_bstate
/*: bus_machine_states*/ ; initial saved_bstate
= sidle;
integer last_bstate
/*: bus_machine_states*/ ; initial last_bstate
= sidle;
integer cstate
/*: cmd_states*/ ; initial cstate
= cmd_rdy;
integer sstate
/*: step_states*/ ; initial sstate
= waiting;
reg [0:7] syncout_active
/*: sync_array*/ ;
//integer i;
initial begin
for (i=0; i<=7; i=i+1) begin
syncout_active[i] = `false;
end
end
reg [0:7] wait_sync
/*: sync_array*/ ;
initial begin
for (i=0; i<=7; i=i+1) begin
wait_sync[i] = `false;
end
end
reg [63 : 0] temp_byte
; initial temp_byte
= 64'hxxxxxxxxxxxxxxxx;
reg [63 : 0] temp_data
; initial temp_data
= 64'hxxxxxxxxxxxxxxxx;
reg [ 3 : 0] byte_enables
; initial byte_enables
= 4'hx;
reg [ 3 : 0] byte_enables_7to4
; initial byte_enables_7to4
= 4'hx;
reg [31 : 0] data_words
; initial data_words
= 32'hxxxxxxxx;
reg [31 : 0] data_words_63to32
; initial data_words_63to32
= 32'hxxxxxxxx;
reg [31 : 0] hexaddress
; initial hexaddress
= 32'hxxxxxxxx;
reg [ 3 : 0] value
; initial value
= 4'hx;
reg [ 7 : 0] config_addr
; initial config_addr
= 8'hxx;
reg [31 : 0] upper_addr
; initial upper_addr
= 32'hxxxxxxxx;
reg [31 : 0] upper_addr_tmp
; initial upper_addr_tmp
= 32'hxxxxxxxx;
reg [31 : 0] addr
; initial addr
= 32'hxxxxxxxx;
reg [ 3 : 0] cmmd
; initial cmmd
= 4'hx;
reg [ 3 : 0] byte_en
; initial byte_en
= 4'hx;
reg [ 3 : 0] byte_en_7to4
; initial byte_en_7to4
= 4'hx;
reg [31 : 0] data_int
; initial data_int
= 32'hxxxxxxxx; //data_int <= dataout
reg [31 : 0] data_int_63to32
; initial data_int_63to32
= 32'hxxxxxxxx; //data_int_63to32 <= dataout_63to32
reg [31 : 0] dataout
; initial dataout
= 32'hffffffff; /*'H'*/
reg [31 : 0] dataout_63to32
; initial dataout_63to32
= 32'hffffffff; /*'H'*/
reg [31 : 0] ad_val
; initial ad_val
= 32'hxxxxxxxx;
reg [63 : 32] d_val
; initial d_val
= 32'hxxxxxxxx;
reg [ 3 : 0] cxbe_val
; initial cxbe_val
= 4'hx;
reg [ 7 : 4] be_val
; initial be_val
= 4'hx;
reg [15 : 0] command_reg
; initial command_reg
= 16'b0000000000000000;
reg [15 : 0] status_reg
; initial status_reg
= 16'b0000000000000000;
reg [ 7 : 0] latency_timer_reg
; initial latency_timer_reg
= 8'b00000000;
reg [31 : 0] last_ad
; initial last_ad
= 32'hffffffff;
reg [ 3 : 0] last_cbe
; initial last_cbe
= 4'hf;
reg [7 : 0] cacheline_size_reg
; initial cacheline_size_reg
= 8'b00000000;
//integer cacheline_size_int ; initial cacheline_size_int = 0;
integer starting_addr
; initial starting_addr
= 0;
reg strobe
; initial strobe
= 1'b0;
reg back2back
; initial back2back
= 1'b0;
reg request
; initial request
= 1'b0;
reg was_wr
; initial was_wr
= 1'b0;
reg same_agnt
; initial same_agnt
= 1'b0;
reg lock
; initial lock
= 1'b0;
reg step_local
; initial step_local
= 1'b0;
reg cmd_ack
; initial cmd_ack
= 1'b0;
reg last_data
; initial last_data
= 1'b0;
reg target_abort
; initial target_abort
= 1'b0;
reg master_abort
; initial master_abort
= 1'b0;
reg data_phase
; initial data_phase
= 1'b0;
reg stepping
; initial stepping
= 1'b0;
reg l_cycle
; initial l_cycle
= 1'b0; // l_cycle <= was_wr
reg sa
; initial sa
= 1'b0; // sa <= same_agnt
reg lock_a
; initial lock_a
= 1'b0; // lock_a <= lock
reg ready
; initial ready
= 1'b0;
reg comp
; initial comp
= 1'b0;
reg cmmd_ready
; initial cmmd_ready
= 1'b0;
reg cmd_in_progress
; initial cmd_in_progress
= 1'b0;
reg back_to_back
; initial back_to_back
= 1'b0;
reg req_val
; initial req_val
= 1'bx;
reg req64_val
; initial req64_val
= 1'bx;
reg frame_val
; initial frame_val
= 1'bx;
reg irdy_val
; initial irdy_val
= 1'bx;
reg lock_val
; initial lock_val
= 1'bx;
reg par_val
; initial par_val
= 1'bx;
reg par64_val
; initial par64_val
= 1'bx;
reg perr_val
; initial perr_val
= 1'bx;
reg trdy_val
; initial trdy_val
= 1'bx;
reg devsel_val
; initial devsel_val
= 1'bx;
reg perr_int
; initial perr_int
= 1'b1 /* 'H' */;
reg time_out
; initial time_out
= 1'b0;
reg dev_to
; initial dev_to
= 1'b0;
reg irdy_oe
; initial irdy_oe
= 1'b0;
reg irdy_int
; initial irdy_int
= 1'b1;
reg frame_int
; initial frame_int
= 1'b1;
reg own_lock
; initial own_lock
= 1'b0;
reg lock_en
; initial lock_en
= 1'b0;
reg lock_int
; initial lock_int
= 1'b0;
reg lock_data_transferred
; initial lock_data_transferred
= 1'b0;
reg last_pack64nn
; initial last_pack64nn
= 1'b1;
integer tc
; initial tc
= 1;
integer delays
; initial delays
= 0;
integer retry_counter
; initial retry_counter
= 0;
integer step_counter
; initial step_counter
= 0;
integer transfer_limit
; initial transfer_limit
= 0;
integer transfer_cnt
; initial transfer_cnt
= 0;
integer delay_cnt
; initial delay_cnt
= 0;
integer cdelay_local
; initial cdelay_local
= 0;
integer cdelay_local1
; initial cdelay_local1
= 0;
integer cdelay_local_tmp
; initial cdelay_local_tmp
= 0;
integer sdelay
; initial sdelay
= 0;
integer timeout_limit
; initial timeout_limit
= 0;
integer counter
/*range 0 : 5*/ ; initial counter
= 0;
integer pci_command
; initial pci_command
= 16; // NONE
integer internal_retry_limit
; initial internal_retry_limit
= 1;
integer to_counter
/*: natural*/ ; initial to_counter
= 0;
reg initialize
; initial initialize
= `true;
reg check_data
; initial check_data
= `false;
reg sync_first
; initial sync_first
= `true;
reg lastcmd_same
; initial lastcmd_same
= `false;
reg lastcmd_back
; initial lastcmd_back
= `false;
reg get_addr
; initial get_addr
= `true;
reg burst_cycle
; initial burst_cycle
= `false;
reg disconnect_a
; initial disconnect_a
= `false;
reg disconnect_b
; initial disconnect_b
= `false;
reg disconnect_c
; initial disconnect_c
= `false;
reg second_be_transfer
; initial second_be_transfer
= `false;
reg second_data_transfer
; initial second_data_transfer
= `false;
reg wait_devsel_delay
; initial wait_devsel_delay
= `false;
reg double_addr
; initial double_addr
= `false;
reg double_addr_tmp
; initial double_addr_tmp
= `false;
reg turn_around_clk
; initial turn_around_clk
= `false;
reg config_cycle
; initial config_cycle
= `false;
reg bus_64
; initial bus_64
= `false;
reg retry64_32
; initial retry64_32
= `false;
reg first_64out
; initial first_64out
= `false;
reg reset_model
; initial reset_model
= `false;
reg old_reset_model
; initial old_reset_model
= `false;
integer /* time */ skew
; initial skew
= 0 * `time_scale_multiplier;
reg cstate_rw
; initial cstate_rw
= `false;
reg addr_64
; initial addr_64
= `false;
reg second_addr
; initial second_addr
= `false;
reg bad_addr_parity
; initial bad_addr_parity
= `false;
reg bad_data_parity
; initial bad_data_parity
= `false;
reg config_par_check
; initial config_par_check
= `false;
reg config_perr_check
; initial config_perr_check
= `false;
reg last_bus_64
; initial last_bus_64
= `false;
reg last_irdy
; initial last_irdy
= `true;
reg last_trdy
; initial last_trdy
= `true;
reg wait_one_clk
; initial wait_one_clk
= `false;
reg address_phase
; initial address_phase
= `false;
reg first
; initial first
= `true;
reg first_a
; initial first_a
= `false;
reg first_b
; initial first_b
= `true;
reg first_command
; initial first_command
= `true;
reg clk_running
; initial clk_running
= `false;
reg clk_sp
; initial clk_sp
= `false;
reg clk_mp
; initial clk_mp
= `false;
reg maintain_check
; initial maintain_check
= `true;
integer /* time */ last_clk_rising
; initial last_clk_rising
= -200 * `time_scale_multiplier;
reg clkrun_value
; initial clkrun_value
= 1'bz;
integer clk_start_count
; initial clk_start_count
= 0;
integer clk_maintain_count
; initial clk_maintain_count
= 0;
integer /* time */ maintain_start
; initial maintain_start
= 0 * `time_scale_multiplier;
integer clkrun_val_l
; initial clkrun_val_l
= 0;
reg clkrun_req
; initial clkrun_req
= `false;
reg pframenn_last
; initial pframenn_last
= 1'bx;
reg type1_access_l
; initial type1_access_l
= `true;
// commands
parameter intr_a = 0;
parameter special_c = 1;
parameter io_r = 2;
parameter io_w = 3;
parameter mem_r = 6;
parameter mem_w = 7;
parameter config_r = 10;
parameter config_w = 11;
parameter read_m = 12;
parameter read_l = 14;
parameter write_i = 15;
parameter none = 16;
parameter config_c = 17;
parameter config_retry_limit = 1;
// responses
//parameter next_cmd = 1;
//parameter ok = 4;
//parameter retry = 5;
//parameter m_abort = 6;
//parameter t_abort = 7;
//parameter dvalid = 8;
//parameter dinvalid = 9;
parameter z_adbus = (32'bzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz);
parameter x_32 = (32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx);
parameter x_64 = (64'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx);
parameter zero_32 = (32'b00000000000000000000000000000000);
parameter z_cxbe = (4'bzzzz);
reg enabled
; initial enabled
= `false;
reg turn
; initial turn
= `false;
reg read_cycle
; initial read_cycle
= `false;
reg write_cycle
; initial write_cycle
= `false;
reg [3 : 0] bits
;
integer pe
; initial pe
= 0;
integer size
; initial size
= 0;
//reg curr_cmd_is_idle ; //initial curr_cmd_is_idle = `false;
integer idle_cycles
; initial idle_cycles
= 0;
integer right
; initial right
= 0;
reg enable
; initial enable
= 1'b1;
reg [1 : 0] mode_local
; initial mode_local
= 2'b00;
integer wakeup_num
; initial wakeup_num
= -1;
reg first_reset
; initial first_reset
= `true;
reg old_enable
; initial old_enable
= 1'b1;
reg [15 : 0] device_id_reg
; initial device_id_reg
= 16'h0000;
reg [15 : 0] vendor_id_reg
; initial vendor_id_reg
= 16'h0000;
reg [7 : 0] revision_id_reg
; initial revision_id_reg
= 8'h00;
reg [23 : 0] class_code_reg
; initial class_code_reg
= 24'h000000;
integer /* time */ max_clk_period_l
; initial max_clk_period_l
= 0 *`time_scale_multiplier;
reg gnc
; initial gnc
= `false;
reg [31 : 0] first_data
;
reg fb2b_ena
; initial fb2b_ena
= 1'b0;
reg idle_done_flag
; initial idle_done_flag
= `false;// makes sure get_nxt_cmd
// is not called till one clock
// later for idle(1).
reg [fm_data_in1:fm_data_in2] next_cmd
; // fm_data_in
initial next_cmd = timing.fm_data_in_init; //updated by controller, used by executer,
//!!8.0 change - used ^^^^ fm_data_in_init in timing
reg tri_pins
; initial tri_pins
= `true;
// define some functions here that convert signals into
// boolean values. this makes it easier to code the state
// machines so that they appear exactly the same as in the
// pci spec. for a given signal x, the function that returns its
// boolean value is x_b.
function b;
input s;
/*return boolean */
reg result ;
begin
case ( s )
1'b1 : begin result = `true;
end
1'b0 : begin result = `false;
end
default begin result = `false;
end
endcase
b = result;
end
endfunction // ;
// Configuration routines
task configure_read;
reg [31 : 0] reg_vector ;
begin
if ( wait_one_clk ) begin // wait one clock for read cycle
wait_one_clk = `false;
end else begin
config_par_check = `true; // to check par on the next clock
config_perr_check = `false;
config_cycle = `false;
This page: |
Created: | Thu Aug 19 11:57:08 1999 |
| From: |
../../../sparc_v8/system/lmc/rtl/pcimaster_fm.v
|