/********************************************** _ _ Cook Darwin __
_ descript: author : Cook.Darwin Version: VERA.0.0 creaded: 2016/10/12 madified: ***********************************************/ `timescale 1ns / 1ps module model_ddr_ip_app #(
parameter ADDR_WIDTH = 27, parameter DATA_WIDTH = 256, parameter MARK_X = "OFF", parameter DISPLAY = "ON"
)(
input clock, input [ADDR_WIDTH-1:0] app_addr, input [2:0] app_cmd, input app_en, input [DATA_WIDTH-1:0] app_wdf_data, input app_wdf_end, input [DATA_WIDTH/8-1:0] app_wdf_mask, input app_wdf_wren, output logic[DATA_WIDTH-1:0] app_rd_data, output logic app_rd_data_end, output logic app_rd_data_valid, output logic app_rdy, output logic app_wdf_rdy, output logic init_calib_complete
);
initial begin
init_calib_complete = 0; #(10us); init_calib_complete = 1;
end
// logic mbx [$];
mailbox wr_mbx = new(); mailbox rd_mbx = new();
task automatic ramdon_signal (int rate,ref logic data); int rt;
forever begin rt = $urandom_range(99,0); if(rt < rate)begin data = 1; end else begin data = 0; end @(posedge clock); #(1ps); end @(negedge clock);
endtask:ramdon_signal
task automatic ramdon_signal_time (int t,int rate,ref logic data); int rt; int cnt;
cnt = 0; while(cnt < t) begin rt = $urandom_range(99,0); if(rt < rate)begin data = 1; cnt ++; end else begin data = 0; end @(posedge clock); end
endtask:ramdon_signal_time
task automatic cmd ();
app_rdy = 1; fork ramdon_signal(99,app_rdy); join_none
endtask:cmd
task automatic write();
app_wdf_rdy = 1; fork ramdon_signal(99,app_wdf_rdy); join_none
endtask:write
task automatic sync_wait(ref logic condition);
forever begin @(posedge clock); if(condition) break; end
endtask:sync_wait
logic [DATA_WIDTH-1:0] data_mem [logic]; logic [ADDR_WIDTH-1:0] addr_queue [$]; logic [DATA_WIDTH-1:0] data_queue [$];
task automatic write_cmd ();
fork forever begin forever begin @(negedge clock); if(app_en && app_rdy && app_cmd == 2'b00)begin break; end end addr_queue.push_back(app_addr); // $display("%t PUSH ADDR %h",$time,app_addr); end join_none
endtask:write_cmd
task automatic write_data (); logic [ADDR_WIDTH-1:0] addr; logic [DATA_WIDTH-1:0] data;
fork forever begin forever begin @(negedge clock); if(app_wdf_rdy && app_wdf_wren) break; end data_queue.push_back(app_wdf_data); // $display("%t PUSH DATA %h",$time,app_wdf_data); if(app_wdf_data==29'h0378) $stop; end forever begin forever begin @(negedge clock); if(data_queue.size() > 0 && addr_queue.size() > 0) break; end addr = addr_queue.pop_front(); data = data_queue.pop_front(); // if( |addr == 1'b0 || addr == 1'b1) data_mem[addr] = data; if(DISPLAY=="ON" && DISPLAY=="TRUE") $display("WRITE DDR ADDR[%h],DATA[%h]",addr,data); end join_none
endtask : write_data
task automatic read_cmd();
// mbx = {}; fork forever begin forever begin @(negedge clock); if(app_en && app_rdy && app_cmd == 2'b01)begin // $display("READ DDR ADDR[%h]",app_addr); wr_mbx.put(app_addr); end end // fork // begin // repeat(40) // @(posedge clock); // mbx.put(app_addr); // $display("PUT MAILBOX FINISH"); // end // join_none // fork // read_resp(50,mbx); // join_none end join_none
endtask:read_cmd
initial begin:CONNECT_MBX int addr; int i;
forever begin @(posedge clock); i = wr_mbx.num(); if(i)begin // $display("WR MAILBOX HAVE DATA"); repeat(20) @(posedge clock); i = wr_mbx.num(); repeat(i) begin wr_mbx.get(addr); rd_mbx.put(addr); // $display("READ CMD SHIFT ADDR[%h]",addr); end end end
end
task automatic read_resp(int rate); int rt; int addr;
// app_rd_data_valid = 0; fork forever begin app_rd_data_valid = 0; // $display("GET ADDR[%h] MAILBOX FINISH",addr); // rt = 0; // repeat(20) // @(posedge clock); while(app_rd_data_valid==0)begin rt = $urandom_range(99,0); if(rt < rate)begin rd_mbx.get(addr); // $display("APP ADDR [%h]",data_s.pop_front); app_rd_data_valid = 1; app_rd_data = data_mem[addr]; // if(MARK_X == "ON" || MARK_X == "TRUE")begin // if(|app_rd_data == 1'bx) // app_rd_data <= '1; // end if(DISPLAY=="ON" && DISPLAY=="TRUE") $display("READ DDR ADDR[%h],DATA[%h]",addr,app_rd_data); foreach(app_rd_data[i])begin if(MARK_X == "ON" || MARK_X == "TRUE")begin if(app_rd_data[i] === 1'bx) // app_rd_data[i] = 1'b1; app_rd_data[i] = $urandom_range(1,0); end end end else begin app_rd_data_valid = 0; end @(posedge clock); end // app_rd_data_valid = 0; end join_none
endtask:read_resp
// task automatic read_resp_simple(); // int len; // fork // forever begin // forever begin // @(posedge clock); // if(app_en && app_rdy && app_cmd == 2'b01) // break; // if(mbx.size()>0) // break; // end // repeat(15) // @(posedge clock); // len = mbx.size(); // if(len > 0)begin // ramdon_signal_time(len,50,app_rd_data_valid); // // for(int i=0;i<len;i++) // // $display(“APP DDR [%h]”,mbx.pop_front); // end // app_rd_data_valid = 0; // end // join_none // endtask:read_resp_simple
// task automatic read_resp_direct(); // int len; // fork // forever begin // @(posedge clock); // if(app_en && app_rdy && app_cmd == 2'b01)begin // app_rd_data_valid = 1; // end else begin // app_rd_data_valid = 0; // end // end // join_none // endtask:read_resp_direct
// always@(posedge clock)begin // if(app_en && app_rdy && app_cmd == 2'b01)begin // app_rd_data_valid = 1; // // app_rd_data = $urandom_range(15,0); // app_rd_data = data_mem; // end else begin // app_rd_data_valid = 0; // end // end
initial begin
write_cmd (); write_data ();
end
initial begin
cmd(); write(); read_cmd(); read_resp(100); // read_resp_simple(); // read_resp_direct();
end
endmodule