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