X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/raggedstone/blobdiff_plain/b983c58b8128671dc7e2c8252af87fbb3aea4134..ebba63a9f3199fec28ffd25951257b6619feb8bf:/dhwk_old/source/pciwbsequ.v diff --git a/dhwk_old/source/pciwbsequ.v b/dhwk_old/source/pciwbsequ.v new file mode 100644 index 0000000..2b09f7f --- /dev/null +++ b/dhwk_old/source/pciwbsequ.v @@ -0,0 +1,295 @@ +// Copyright (C) 2005 Peio Azkarate, peio@opencores.org +// +// This source file is free software; you can redistribute it +// and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; +// either version 2.1 of the License, or (at your option) any +// later version. +// + +(* signal_encoding = "user" *) +(* safe_implementation = "yes" *) + +module pciwbsequ_new ( clk_i, nrst_i, cmd_i, cbe_i, frame_i, irdy_i, devsel_o, + trdy_o, adrcfg_i, adrmem_i, pciadrLD_o, pcidOE_o, parOE_o, wbdatLD_o, + wbrgdMX_o, wbd16MX_o, wrcfg_o, rdcfg_o, wb_sel_o, wb_we_o, wb_stb_o, + wb_cyc_o, wb_ack_i, wb_err_i, debug_init, debug_access ); + + // General + input clk_i; + input nrst_i; + // pci + // adr_i + input [3:0] cmd_i; + input [3:0] cbe_i; + input frame_i; + input irdy_i; + output devsel_o; + output trdy_o; + // control + input adrcfg_i; + input adrmem_i; + output pciadrLD_o; + output pcidOE_o; + output reg parOE_o; + output wbdatLD_o; + output wbrgdMX_o; + output wbd16MX_o; + output wrcfg_o; + output rdcfg_o; + // whisbone + output [1:0] wb_sel_o; + output wb_we_o; + inout wb_stb_o; + output wb_cyc_o; + input wb_ack_i; + input wb_err_i; + // debug signals + output reg debug_init; + output reg debug_access; + + //type PciFSM is ( PCIIDLE, B_BUSY, S_DATA1, S_DATA2, TURN_AR ); + //wire pst_pci : PciFSM; + //wire nxt_pci : PciFSM; + + // typedef enum reg [2:0] { + // RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW + // } color_t; + // + // color_t my_color = GREEN; + + // parameter PCIIDLE = 2'b00; + // parameter B_BUSY = 2'b01; + // parameter S_DATA1 = 2'b10; + // parameter S_DATA2 = 2'b11; + // parameter TURN_AR = 3'b100; + + reg [2:0] pst_pci; + reg [2:0] nxt_pci; + + parameter [2:0] + PCIIDLE = 3'b000, + B_BUSY = 3'b001, + S_DATA1 = 3'b010, + S_DATA2 = 3'b011, + TURN_AR = 3'b100; + + + initial begin + pst_pci = 3'b000; + end + + initial begin + nxt_pci = 3'b000; + end + + wire sdata1; + wire sdata2; + wire idleNX; + wire sdata1NX; + wire sdata2NX; + wire turnarNX; + wire idle; + reg devselNX_n; + reg trdyNX_n; + reg devsel; + reg trdy; + wire adrpci; + wire acking; + wire rdcfg; + reg targOE; + reg pcidOE; + + // always @(nrst_i or clk_i or nxt_pci) + always @(negedge nrst_i or posedge clk_i) + begin + if( nrst_i == 0 ) + pst_pci <= PCIIDLE; + else + pst_pci <= nxt_pci; + end + + // always @(negedge nrst_i or posedge clk_i) + always @( pst_pci or frame_i or irdy_i or adrcfg_i or adrpci or acking ) + begin + devselNX_n <= 1'b1; + trdyNX_n <= 1'b1; + case (pst_pci) + PCIIDLE : + begin + if ( frame_i == 0 ) + nxt_pci <= B_BUSY; + else + nxt_pci <= PCIIDLE; + end + B_BUSY: + if ( adrpci == 0 ) + nxt_pci <= TURN_AR; + else + begin + nxt_pci <= S_DATA1; + devselNX_n <= 0; + end + S_DATA1: + if ( acking == 1 ) + begin + nxt_pci <= S_DATA2; + devselNX_n <= 0; + trdyNX_n <= 0; + end + else + begin + nxt_pci <= S_DATA1; + devselNX_n <= 0; + end + S_DATA2: + if ( frame_i == 1 && irdy_i == 0 ) + nxt_pci <= TURN_AR; + else + begin + nxt_pci <= S_DATA2; + devselNX_n <= 0; + trdyNX_n <= 0; + end + TURN_AR: + if ( frame_i == 1 ) + nxt_pci <= PCIIDLE; + else + nxt_pci <= TURN_AR; + endcase + end + + // FSM control signals + assign adrpci = adrmem_i; + + assign acking = ( + ( wb_ack_i == 1 || wb_err_i == 1 ) || + ( adrcfg_i == 1 && irdy_i == 0) + ) ? 1'b1 : 1'b0; + + // FSM derived Control signals + assign idle = ( pst_pci <= PCIIDLE ) ? 1'b1 : 1'b0; + assign sdata1 = ( pst_pci <= S_DATA1 ) ? 1'b1 : 1'b0; + assign sdata2 = ( pst_pci <= S_DATA2 ) ? 1'b1 : 1'b0; + assign idleNX = ( nxt_pci <= PCIIDLE ) ? 1'b1 : 1'b0; + assign sdata1NX = ( nxt_pci <= S_DATA1 ) ? 1'b1 : 1'b0; + assign sdata2NX = ( nxt_pci <= S_DATA2 ) ? 1'b1 : 1'b0; + assign turnarNX = ( nxt_pci <= TURN_AR ) ? 1'b1 : 1'b0; + + // PCI Data Output Enable + // always @( nrst_i or clk_i or cmd_i [0] or sdata1NX or turnarNX ) + always @(negedge nrst_i or posedge clk_i) + begin + if ( nrst_i == 0 ) + pcidOE <= 0; + else + if ( sdata1NX == 1 && cmd_i [0] == 0 ) + pcidOE <= 1; + else + if ( turnarNX == 1 ) + pcidOE <= 0; + end + + assign pcidOE_o = pcidOE; + + // PAR Output Enable + // PCI Read data phase + // PAR is valid 1 cicle after data is valid + // always @( nrst_i or clk_i or cmd_i [0] or sdata2NX or turnarNX ) + always @(negedge nrst_i or posedge clk_i) + begin + if ( nrst_i == 0 ) + parOE_o <= 0; + else + if ( ( sdata2NX == 1 || turnarNX == 1 ) && cmd_i [0] == 0 ) + parOE_o <= 1; + else + parOE_o <= 0; + end + + // Target s/t/s signals OE control + // targOE <= '1' when ( idle = '0' and adrpci = '1' ) else '0'; + // always @( nrst_i or clk_i or sdata1NX or idleNX ) + always @(negedge nrst_i or posedge clk_i) + begin + if ( nrst_i == 0 ) + targOE <= 0; + else + if ( sdata1NX == 1 ) + targOE <= 1; + else + if ( idleNX == 1 ) + targOE <= 0; + end + + // WHISBONE outs + assign wb_cyc_o = (adrmem_i == 1 && sdata1 == 1) ? 1'b1 : 1'b0; + assign wb_stb_o = (adrmem_i == 1 && sdata1 == 1 && irdy_i == 0 ) ? 1'b1 : 1'b0; + + // PCI(Little endian) to WB(Big endian) + assign wb_sel_o [1] = (! cbe_i [0]) || (! cbe_i [2]); + assign wb_sel_o [0] = (! cbe_i [1]) || (! cbe_i [3]); + + assign wb_we_o = cmd_i [0]; + + // Syncronized PCI outs + always @(negedge nrst_i or posedge clk_i) + begin + if( nrst_i == 0 ) + begin + devsel <= 1; + trdy <= 1; + end + else + begin + devsel <= devselNX_n; + trdy <= trdyNX_n; + end + end + + assign devsel_o = ( targOE == 1 ) ? devsel : 1'bZ; + assign trdy_o = ( targOE == 1 ) ? trdy : 1'bZ; + + // rd/wr Configuration Space Registers + assign wrcfg_o = ( + adrcfg_i == 1 && + cmd_i [0] == 1 && + sdata2 == 1 + ) ? 1'b1 : 1'b0; + + assign rdcfg = ( + adrcfg_i == 1 && + cmd_i [0] == 0 && + (sdata1 == 1 || sdata2 == 1) + ) ? 1'b1 : 1'b0; + + assign rdcfg_o = rdcfg; + + // LoaD enable signals + assign pciadrLD_o = ! frame_i; + assign wbdatLD_o = wb_ack_i; + + // Mux control signals + assign wbrgdMX_o = ! rdcfg; + assign wbd16MX_o = (cbe_i [3] == 0 || cbe_i [2] == 0) ? 1'b1 : 1'b0; + + // debug outs + always @(negedge nrst_i or posedge clk_i) + begin + if ( nrst_i == 0 ) + debug_init <= 0; + else + if (devsel == 0) + debug_init <= 1; + end + + always @(negedge nrst_i or posedge clk_i) + begin + if ( nrst_i == 0 ) + debug_access <= 0; + else + if (wb_stb_o == 1) + debug_access <= 1; + end + +endmodule