📄 pci_wb_master.v
字号:
// wire for read attempt - 1 when PCI Target is attempting a read and PCIR_FIFO is not full !// because of transaction ordering, PCI Master must not start read untill all writes are done -> at that// moment PCIW_FIFO is empty !!! (when read is pending PCI Target will block new reads and writes)wire r_attempt = ( pci_tar_read_request && !w_attempt && pciw_fifo_empty_in ) ; // Signal is used for reads on WB, when there is retry!reg first_wb_data_access ;reg last_data_from_pciw_fifo ; // signal tells when there is last data in pciw_fiforeg last_data_from_pciw_fifo_reg ;reg last_data_to_pcir_fifo ; // signal tells when there will be last data for pcir_fifo// Logic used in State Machine logic implemented out of State Machine because of less delay!always@(posedge wb_clock_in or posedge reset_in)begin if (reset_in) last_data_from_pciw_fifo <= #`FF_DELAY 1'b0 ; else begin if ((pciw_fifo_renable_out) && (pciw_fifo_control_in[`LAST_CTRL_BIT] || pciw_fifo_almost_empty_in)) // if last data is going to be transfered last_data_from_pciw_fifo <= #`FF_DELAY 1'b1 ; // signal for last data from PCIW_FIFO else last_data_from_pciw_fifo <= #`FF_DELAY 1'b0 ; endend reg read_count_load; reg read_count_enable; reg [(`PCIR_ADDR_LENGTH - 1):0] max_read_count ; always@(pci_cache_line_size or cache_lsize_not_zero or pci_tar_cmd) begin if (cache_lsize_not_zero) if ( (pci_cache_line_size >= `PCIR_DEPTH) || (~pci_tar_cmd[1] && ~pci_tar_cmd[0]) ) // If cache line size is larger than FIFO or BC_MEM_READ_MUL command is performed! max_read_count = `PCIR_DEPTH - 1'b1; else max_read_count = pci_cache_line_size ; else max_read_count = 1'b1; end reg [(`PCIR_ADDR_LENGTH - 1):0] read_count ; // cache line bound indicator - it signals when data for one complete cacheline was read wire read_bound_comb = ~|( { read_count[(`PCIR_ADDR_LENGTH - 1):2], read_count[0] } ) ; reg read_bound ; always@(posedge wb_clock_in or posedge reset_in) begin if ( reset_in ) read_bound <= #`FF_DELAY 1'b0 ; else if (read_count_load) read_bound <= #`FF_DELAY 1'b0 ; else if ( read_count_enable ) read_bound <= #`FF_DELAY read_bound_comb ; end // down counter with load always@(posedge reset_in or posedge wb_clock_in) begin if (reset_in) read_count <= #`FF_DELAY 0 ; else if (read_count_load) read_count <= #`FF_DELAY max_read_count ; else if (read_count_enable) read_count <= #`FF_DELAY read_count - 1'b1 ; end// Logic used in State Machine logic implemented out of State Machine because of less delay!// definition of signal telling, when there is last data written into FIFOalways@(pci_tar_cmd or pci_tar_burst_ok or read_bound)begin // burst is OK for reads when there is ((MEM_READ_LN or MEM_READ_MUL) and AD[1:0]==2'b00) OR // (MEM_READ and Prefetchable_IMAGE and AD[1:0]==2'b00) -> pci_tar_burst_ok case ({pci_tar_cmd, pci_tar_burst_ok}) {`BC_MEM_READ, 1'b1}, {`BC_MEM_READ_LN, 1'b1} : begin // when burst cycle if (read_bound) last_data_to_pcir_fifo = 1'b1 ; else last_data_to_pcir_fifo = 1'b0 ; end {`BC_MEM_READ_MUL, 1'b1} : begin // when burst cycle if (read_bound) last_data_to_pcir_fifo = 1'b1 ; else last_data_to_pcir_fifo = 1'b0 ; end default : // {`BC_IO_READ, 1'b0}, // {`BC_IO_READ, 1'b1}, // {`BC_MEM_READ, 1'b0}, // {`BC_MEM_READ_LN, 1'b0}, // {`BC_MEM_READ_MUL, 1'b0}: begin // when single cycle last_data_to_pcir_fifo = 1'b1 ; end endcaseendreg wait_for_wb_response ;`ifdef PCI_WBM_NO_RESPONSE_CNT_DISABLEwire set_retry = 1'b0 ;`elsereg [3:0] wb_no_response_cnt ;reg [3:0] wb_response_value ;reg set_retry ; // // internal WB no response retry generator counter!always@(posedge reset_in or posedge wb_clock_in)begin if (reset_in) wb_no_response_cnt <= #`FF_DELAY 4'h0 ; else wb_no_response_cnt <= #`FF_DELAY wb_response_value ;end// internal WB no response retry generator logicalways@(wait_for_wb_response or wb_no_response_cnt)begin if (wb_no_response_cnt == 4'h8) // when there isn't response for 8 clocks, set internal retry begin wb_response_value = 4'h0 ; set_retry = 1'b1 ; end else begin if (wait_for_wb_response) wb_response_value = wb_no_response_cnt + 1'h1 ; // count clocks when no response else wb_response_value = 4'h0 ; set_retry = 1'b0 ; endend`endifwire retry = wb_rty_i || set_retry ; // retry signal - logic OR function between wb_rty_i and internal WB no response retry!reg [7:0] rty_counter ; // output from retry counterreg [7:0] rty_counter_in ; // input value - output value + 1 OR output valuereg rty_counter_almost_max_value ; // signal tells when retry counter riches maximum value - 1!reg reset_rty_cnt ; // signal for asynchronous reset of retry counter after each complete transfere// sinchronous signal after each transfere and asynchronous signal 'reset_rty_cnt' after reset // for reseting the retry counteralways@(posedge reset_in or posedge wb_clock_in)begin if (reset_in) reset_rty_cnt <= #`FF_DELAY 1'b1 ; // asynchronous set when reset signal is active else reset_rty_cnt <= #`FF_DELAY wb_ack_i || wb_err_i || last_data_transferred ; // synchronous set after completed transfereend// Retry counter register controlalways@(posedge reset_in or posedge wb_clock_in)begin if (reset_in) rty_counter <= #`FF_DELAY 8'h00 ; else begin if (reset_rty_cnt) rty_counter <= #`FF_DELAY 8'h00 ; else if (retry) rty_counter <= #`FF_DELAY rty_counter_in ; endend// Retry counter logicalways@(rty_counter)begin if(rty_counter == `WB_RTY_CNT_MAX - 1'b1) // stop counting begin rty_counter_in = rty_counter ; rty_counter_almost_max_value = 1'b1 ; end else begin rty_counter_in = rty_counter + 1'b1 ; // count up rty_counter_almost_max_value = 1'b0 ; endend reg [31:0] addr_cnt_out ; // output value from address counter to WB ADDRESS outputreg [31:0] addr_cnt_in ; // input address value to address counterreg addr_into_cnt ; // control signal for loading starting address into counterreg addr_into_cnt_reg ; reg addr_count ; // control signal for count enablereg [3:0] bc_register ; // used when error occures during writes!// wb address counter register controlalways@(posedge wb_clock_in or posedge reset_in)begin if (reset_in) // reset counter begin addr_cnt_out <= #`FF_DELAY 32'h0000_0000 ; bc_register <= #`FF_DELAY 4'h0 ; addr_into_cnt_reg <= #`FF_DELAY 1'b0; end else begin addr_cnt_out <= #`FF_DELAY addr_cnt_in ; // count up or hold value depending on cache line counter logic addr_into_cnt_reg <= #`FF_DELAY addr_into_cnt; if (addr_into_cnt) bc_register <= #`FF_DELAY pciw_fifo_cbe_in ; endend// when '1', the bus command is IO command - not supported commands are checked in pci_decoder moduleswire io_memory_bus_command = !pci_tar_cmd[3] && !pci_tar_cmd[2] ;// wb address counter logicalways@(addr_into_cnt or r_attempt or addr_count or pciw_fifo_addr_data_in or pci_tar_address or addr_cnt_out or io_memory_bus_command)begin if (addr_into_cnt) // load starting address into counter begin if (r_attempt) begin // if read request, then load read addresss from PCI Target addr_cnt_in = {pci_tar_address[31:2], pci_tar_address[1] && io_memory_bus_command, pci_tar_address[0] && io_memory_bus_command} ; end else begin // if not read request, then load write address from PCIW_FIFO addr_cnt_in = pciw_fifo_addr_data_in[31:0] ; end end else if (addr_count) begin addr_cnt_in = addr_cnt_out + 3'h4 ; // count up for 32-bit alligned address end else begin addr_cnt_in = addr_cnt_out ; endendreg retried ; // Signal is output value from FF and is set for one clock period after retried_d is setreg retried_d ; // Signal is set whenever cycle is retried and is input to FF for delaying -> used in S_IDLE statereg retried_write;reg rty_i_delayed; // Dignal used for determinig the source of retry!reg first_data_is_burst ; // Signal is set in S_WRITE or S_READ states, when data transfere is burst!reg first_data_is_burst_reg ;wire burst_transfer ; // This signal is set when data transfere is burst and is reset with RESET or last data transferedreg burst_chopped; // This signal is set when WB_SEL_O is changed during burst write transactionreg burst_chopped_delayed;// FFs output signals tell, when there is first data out from FIFO (for BURST checking)// and for delaying retried signalalways@(posedge wb_clock_in or posedge reset_in)begin if (reset_in) // reset signals begin retried <= #`FF_DELAY 1'b0 ; retried_write <= #`FF_DELAY 1'b0 ; rty_i_delayed <= #`FF_DELAY 1'B0 ; end else begin retried <= #`FF_DELAY retried_d ; // delaying retried signal retried_write <= #`FF_DELAY retried ; rty_i_delayed <= #`FF_DELAY wb_rty_i ; endend// Determinig if first data is a part of BURST or just a single transfere!always@(addr_into_cnt or r_attempt or pci_tar_burst_ok or max_read_count or pciw_fifo_control_in or pciw_fifo_empty_in)begin if (addr_into_cnt) begin if (r_attempt) begin // burst is OK for reads when there is ((MEM_READ_LN or MEM_READ_MUL) and AD[1:0]==2'b00) OR // (MEM_READ and Prefetchable_IMAGE and AD[1:0]==2'b00) -> pci_tar_burst_ok if (pci_tar_burst_ok && (max_read_count != 8'h1)) first_data_is_burst = 1'b1 ; else first_data_is_burst = 1'b0 ; end else begin first_data_is_burst = 1'b0 ; end end else first_data_is_burst = pciw_fifo_control_in[`BURST_BIT] && ~pciw_fifo_empty_in && ~pciw_fifo_control_in[`LAST_CTRL_BIT] /*&& ~pciw_fifo_control_in[`DATA_ERROR_CTRL_BIT]*/;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -