📄 wb_tb.v
字号:
begin if (~wbr_almost_full) begin $display("Almost full status generation test for WBR failed") ; $stop ; end end end end wbr_wenable <= #`FF_DELAY 1'b0 ; @(posedge pci_clock) begin if (~wbr_full) begin $display("Full status generation test for WBR failed") ; $stop ; end end end begin:empty_FIFO rindex = 0 ; wait (wbr_full) ; @(posedge wb_clock) wbr_renable <= #`FF_DELAY 1'b1 ; while(rindex < (`WBR_DEPTH - 1)) begin rindex = rindex + 1 ; @(posedge wb_clock) begin if ((wbr_data_out != rindex) || (rindex[3:0] != wbr_control_out) || (rindex[7:4] != wbr_be_out)) begin $display("Full/Empty status generation test failed for WBR fifo!"); $stop ; end if (rindex == `WBR_DEPTH - 1) begin if (~wbr_almost_empty) begin $display("Almost empty status generation test for WBR failed") ; $stop ; end end end end wbr_renable <= #`FF_DELAY 1'b0 ; @(posedge wb_clock) begin if (~wbr_empty) begin $display("Empty status generation test for WBR failed") ; $stop ; end end end endendtasktask simultaneous_operation; integer i ; integer wbw_data_incoming ; reg[(`WBW_ADDR_LENGTH - 1):0] wb_num_of_writes ; reg[(`WBR_ADDR_LENGTH - 1):0] wb_num_of_reads ; reg[(`WBR_ADDR_LENGTH - 1):0] pci_num_of_writes ; reg[3:0] wbw_cbe_outgoing ; reg[31:0] wbw_data_outgoing ; reg[3:0] wbr_be_outgoing ; reg[31:0] wbr_data_outgoing ; integer decision ; reg read_request ;begin // initialize data wbw_data_in <= 32'd0 ; wbw_control_in <= 4'h0 ; wbw_cbe_in <= 4'he ; wbw_data_outgoing <= 32'd1; wbw_cbe_outgoing <= 4'hf; read_request <= 1'b0 ; wbr_be_outgoing <= 4'hf ; wbr_data_outgoing <= 32'd1 ; wbr_data_in <= 32'd0 ; wbr_control_in <= 4'h1 ; wbr_be_in <= 4'he ;forkbegin:wb_requests forever begin // random decision on whether current request is a read or a write decision = $random(wbw_data_incoming) ; if (decision <= 32'd2_147_000_000) begin // write operation if(~wbw_full && ~wbw_almost_full && ~read_request) begin // WBW fifo is not full or almost full, so it can accomodate one transaction at least // get random transaction length wb_num_of_writes = $random ; @(posedge wb_clock) begin wbw_wenable <= #`FF_DELAY 1'b1 ; //assert write enable and assign control to address wbw_data_in <= #`FF_DELAY wbw_data_in + 1 ; wbw_cbe_in <= #`FF_DELAY wbw_cbe_in + 1 ; wbw_control_in <= #`FF_DELAY `ADDRESS ; end @(posedge wb_clock) ; // address is written on the first clock edge @(negedge wb_clock) ; // wait 1/2 clock to see if after address was written fifo is almost empty while ((wb_num_of_writes > 1) && (~wbw_almost_full)) begin // prepare new data wbw_data_in <= #`FF_DELAY wbw_data_in + 1 ; wbw_control_in <= #`FF_DELAY 4'h1 ; wbw_cbe_in <= #`FF_DELAY wbw_cbe_in + 1 ; @(posedge wb_clock) // write new data wb_num_of_writes <= wb_num_of_writes - 1 ; @(negedge wb_clock) ; // combinatorial monitoring of almost full avoided by waiting half a cycle end //while // prepare last data wbw_data_in <= #`FF_DELAY wbw_data_in + 1 ; wbw_control_in <= #`FF_DELAY `LAST ; wbw_cbe_in <= #`FF_DELAY wbw_cbe_in + 1 ; @(posedge wb_clock) //last data of transaction written wbw_wenable <= #`FF_DELAY 1'b0 ; @(negedge wb_clock) ; end //if else // since it was a write request and FIFO cannot accommodate another transaction, wait one cycle @(posedge wb_clock) ; end else begin // it's a read request // only accept read request if no other is pending if (~read_request) begin @(posedge wb_clock) // initiate read request read_request <= #`FF_DELAY 1'b1 ; // wait for FIFO to be filled and transaction be ready wait(~wbr_empty && wbr_transaction_ready) ; // random number of reads wb is prepared to do wb_num_of_reads = $random ; // first posedge of wb clock when transaction is ready - assert read enable @(posedge wb_clock) wbr_renable <= #`FF_DELAY 1'b1 ; // until whole transaction or random number of reads is performed do a read @(negedge wb_clock) ; //wait if maybe first transaction is the last while((wb_num_of_reads > 1) && (~wbr_almost_empty) && (wbr_control_out != `LAST)) begin @(posedge wb_clock) begin if ((wbr_data_out != wbr_data_outgoing) || (wbr_be_out != wbr_be_outgoing)) begin $display("Operational test for WBR FIFO failed") ; $stop ; end // prepare new set of outgoing data for comparison wbr_data_outgoing <= #`FF_DELAY wbr_data_outgoing + 1; wbr_be_outgoing <= #`FF_DELAY wbr_be_outgoing + 1 ; wb_num_of_reads <= wb_num_of_reads - 1 ; @(negedge wb_clock) ; // avoiding combinatorial logic for monitoring almost full or control out by waiting 1/2 cycle end end // read last data entry @(posedge wb_clock) begin if ((wbr_data_out != wbr_data_outgoing) || (wbr_be_out != wbr_be_outgoing)) begin $display("Operational test for WBR FIFO failed") ; $stop ; end wbr_renable <= #`FF_DELAY 1'b0 ; end // after last intended data is read, flush wbr_fifo @(posedge wb_clock) begin if(~wbr_empty) begin wbr_flush <= #`FF_DELAY 1'b1 ; @(posedge wb_clock) wbr_flush <= #`FF_DELAY 1'b0 ; end //if end // posedge end else @(posedge wb_clock) ; end //else end //foreverend //wb_requestsbegin:pci_completions // wait until read request is present or at least one write is posted forever begin wait ((~wbw_empty && wbw_transaction_ready) || (read_request && wbr_empty)) ; // all the writes must finish before a read can be processed if (~wbw_empty && wbw_transaction_ready) begin // first posedge of pci clock when transaction is ready - assert read enable @(posedge pci_clock) wbw_renable <= #`FF_DELAY 1'b1 ; // first entry must be address @(posedge pci_clock) begin if ((wbw_data_out != wbw_data_outgoing) || (wbw_cbe_out != wbw_cbe_outgoing) || (wbw_control_out != `ADDRESS)) begin $display("Operational test for WBW FIFO failed") ; $stop ; end //if wbw_data_outgoing <= #`FF_DELAY wbw_data_outgoing + 1 ; wbw_cbe_outgoing <= #`FF_DELAY wbw_cbe_outgoing + 1 ; end //posedge // wait for negedge - maybe first data is also last @(negedge pci_clock) ; while ((wbw_control_out != `LAST) && (~wbw_almost_empty)) begin @(posedge pci_clock) begin if ((wbw_data_out != wbw_data_outgoing) || (wbw_cbe_out != wbw_cbe_outgoing)) begin $display("Operational test for WBW FIFO failed") ; $stop ; end // prepare new set of outgoing data for comparison wbw_data_outgoing <= #`FF_DELAY wbw_data_outgoing + 1; wbw_cbe_outgoing <= #`FF_DELAY wbw_cbe_outgoing + 1 ; @(negedge pci_clock) ; // avoiding combinatorial logic for monitoring almost full or control out by waiting 1/2 cycle end end // read last data entry @(posedge pci_clock) begin if ((wbw_data_out != wbw_data_outgoing) || (wbw_cbe_out != wbw_cbe_outgoing) || (wbw_control_out != `LAST)) begin $display("Operational test for WBW FIFO failed") ; $stop ; end wbw_renable <= #`FF_DELAY 1'b0 ; // prepare new set of outgoing data for comparison wbw_data_outgoing <= #`FF_DELAY wbw_data_outgoing + 1; wbw_cbe_outgoing <= #`FF_DELAY wbw_cbe_outgoing + 1 ; end //posedge // turnaround cycle @(posedge pci_clock) ; end // if else if (read_request && wbr_empty) begin // read request is present - fill the FIFO pci_num_of_writes = $random ; // reads are of random length @(posedge pci_clock) begin if (pci_num_of_writes < `WBR_DEPTH'h2) wbr_control_in <= #`FF_DELAY `LAST ; else wbr_control_in <= #`FF_DELAY 4'h1 ; wbr_wenable <= #`FF_DELAY 1'b1 ; wbr_data_in <= #`FF_DELAY wbr_data_in + 1 ; wbr_be_in <= #`FF_DELAY wbr_be_in + 1 ; // set wbr outgoing to new value wbr_data_outgoing <= wbr_data_in + 1 ; wbr_be_outgoing <= wbr_be_in + 1; end // posedge @(negedge pci_clock) ; if (wbr_control_in != `LAST) begin while ((pci_num_of_writes > 1) && (~wbr_almost_full)) begin @(posedge pci_clock) begin // prepare data for next write wbr_data_in <= #`FF_DELAY wbr_data_in + 1 ; wbr_be_in <= #`FF_DELAY wbr_be_in + 1 ; pci_num_of_writes <= pci_num_of_writes - 1 ; end // posedge @(negedge pci_clock) ; // avoid combinatorial logic for almost full monitoring end //while // write last data phase wbr_control_in <= #`FF_DELAY `LAST ; @(posedge pci_clock) begin // last data is written wbr_wenable <= #`FF_DELAY 1'b0 ; read_request <= #`FF_DELAY 1'b0 ; end //posedge end //if else begin // first is also the last data - wait for posedge and finish @(posedge pci_clock) begin wbr_wenable <= #`FF_DELAY 1'b0 ; read_request <= #`FF_DELAY 1'b0 ; end //posedge end //else @(posedge pci_clock) ; // turnaround end //else if else @(posedge pci_clock) ; end //foreverend //pci_completionsbegin:timing #1000000 $stop ;end //timingjoinend endtask WBW_WBR_FIFOS #(`WBW_DEPTH, `WBW_ADDR_LENGTH, `WBR_DEPTH, `WBR_ADDR_LENGTH) wbw_wbr (.wb_clock_in(wb_clock), .pci_clock_in(pci_clock), .reset_in(reset), .wbw_wenable_in(wbw_wenable), .wbw_addr_data_in(wbw_data_in), .wbw_cbe_in(wbw_cbe_in), .wbw_control_in(wbw_control_in), .wbw_renable_in(wbw_renable), .wbw_addr_data_out(wbw_data_out), .wbw_cbe_out(wbw_cbe_out), .wbw_control_out(wbw_control_out), .wbw_flush_in(1'b0), .wbw_almost_full_out(wbw_almost_full), .wbw_full_out(wbw_full), .wbw_almost_empty_out(wbw_almost_empty), .wbw_empty_out(wbw_empty), .wbw_transaction_ready_out(wbw_transaction_ready), .wbr_wenable_in(wbr_wenable), .wbr_data_in(wbr_data_in), .wbr_be_in(wbr_be_in), .wbr_control_in(wbr_control_in), .wbr_renable_in(wbr_renable), .wbr_data_out(wbr_data_out), .wbr_be_out(wbr_be_out), .wbr_control_out(wbr_control_out), .wbr_flush_in(wbr_flush), .wbr_almost_full_out(wbr_almost_full), .wbr_full_out(wbr_full), .wbr_almost_empty_out(wbr_almost_empty), .wbr_empty_out(wbr_empty), .wbr_transaction_ready_out(wbr_transaction_ready)) ;endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -