⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci_wb_master.v

📁 这是用pci-wishbone核和16450串口核在xilinx的fpga上实现的串口程序
💻 V
📖 第 1 页 / 共 4 页
字号:
// 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 + -