1 //////////////////////////////////////////////////////////////////////
3 //// File name: pci_spoci_ctrl ////
5 //// This file is part of the "PCI bridge" project ////
6 //// http://www.opencores.org/cores/pci/ ////
9 //// - Miha Dolenc (mihad@opencores.org) ////
12 //////////////////////////////////////////////////////////////////////
14 //// Copyright (C) 2004 Miha Dolenc, mihad@opencores.org ////
16 //// This source file may be used and distributed without ////
17 //// restriction provided that this copyright statement is not ////
18 //// removed from the file and that any derivative work contains ////
19 //// the original copyright notice and the associated disclaimer. ////
21 //// This source file is free; you can redistribute it ////
22 //// and/or modify it under the terms of the GNU Lesser General ////
23 //// Public License as published by the Free Software Foundation; ////
24 //// either version 2.1 of the License, or (at your option) any ////
25 //// later version. ////
27 //// This source is distributed in the hope that it will be ////
28 //// useful, but WITHOUT ANY WARRANTY; without even the implied ////
29 //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
30 //// PURPOSE. See the GNU Lesser General Public License for more ////
33 //// You should have received a copy of the GNU Lesser General ////
34 //// Public License along with this source; if not, download it ////
35 //// from http://www.opencores.org/lgpl.shtml ////
37 //////////////////////////////////////////////////////////////////////
39 // CVS Revision History
41 // $Log: pci_spoci_ctrl.v,v $
42 // Revision 1.1 2007-03-20 17:50:56 sithglan
45 // Revision 1.1 2004/01/24 11:54:18 mihad
46 // Update! SPOCI Implemented!
50 `include "pci_constants.v"
52 // synopsys translate_off
53 `include "timescale.v"
54 // synopsys translate_on
78 parameter tx_rx_state_width = 9 ;
79 parameter tx_rx_idle = 'h1 ;
80 parameter tx_rx_start = 'h2 ;
81 parameter tx_rx_restart = 'h4 ;
82 parameter tx_rx_send_bits = 'h8 ;
83 parameter tx_rx_rec_bits = 'h10 ;
84 parameter tx_rx_send_ack = 'h20 ;
85 parameter tx_rx_rec_ack = 'h40 ;
86 parameter tx_rx_send_nack = 'h80 ;
87 parameter tx_rx_stop = 'h100 ;
89 parameter rw_seq_state_width = 5 ;
90 parameter rw_seq_idle = 'h1 ;
91 parameter rw_seq_tx_ctrl = 'h2 ;
92 parameter rw_seq_tx_adr = 'h4 ;
93 parameter rw_seq_tx_byte = 'h8 ;
94 parameter rw_seq_rx_byte = 'h10 ;
97 parameter cnt_width = 9 ;
98 parameter period_cnt = 334 ;
102 parameter cnt_width = 10 ;
103 parameter period_cnt = 667 ;
109 input do_rnd_read_i ,
113 output write_done_o ,
117 input [10: 0] adr_i ;
118 input [ 7: 0] dat_i ;
119 output [ 7: 0] dat_o ;
121 input pci_spoci_sda_i ;
123 output pci_spoci_sda_oe_o ,
132 reg pci_spoci_sda_oe_o ,
136 reg clk_gen_cnt_clr ;
137 reg [cnt_width - 1:0] clk_gen_cnt ;
139 reg [tx_rx_state_width - 1:0] tx_rx_state ;
140 reg [tx_rx_state_width - 1:0] tx_rx_next_state ;
151 always@(posedge clk_i or posedge reset_i)
157 tx_rx_state <= tx_rx_idle ;
160 pci_spoci_sda_oe_o <= 1'b1 ;
161 pci_spoci_scl_oe_o <= 1'b1 ;
164 `ifdef ACTIVE_HIGH_OE
165 pci_spoci_sda_oe_o <= 1'b0 ;
166 pci_spoci_scl_oe_o <= 1'b0 ;
173 tx_rx_state <= tx_rx_next_state ;
177 else if (clk_gen_cnt_en)
178 clk_gen_cnt <= clk_gen_cnt + 1'b1 ;
184 pci_spoci_sda_oe_o <= ~sda_oe ;
187 `ifdef ACTIVE_HIGH_OE
188 pci_spoci_sda_oe_o <= sda_oe ;
195 pci_spoci_scl_oe_o <= ~scl_oe ;
198 `ifdef ACTIVE_HIGH_OE
199 pci_spoci_scl_oe_o <= scl_oe ;
204 sda_i_reg <= pci_spoci_sda_i ;
208 reg [ 7: 0] tx_shift_reg ;
246 clk_gen_cnt_clr = 1'b0 ;
247 clk_gen_cnt_en = 1'b0 ;
248 tx_rx_next_state = tx_rx_state ;
249 tx_rx_sm_idle = 1'b0 ;
258 sda_i_reg_en = 1'b0 ;
268 tx_rx_sm_idle = 1'b1 ;
270 // from idle state, the only transition can be to the send start bit
273 tx_rx_next_state = tx_rx_start ;
274 clk_gen_cnt_clr = 1'b1 ;
280 clk_gen_cnt_en = 1'b1 ;
283 // start bit is sent by transmiting 0 on the sda line
284 if (clk_gen_cnt == (period_cnt >> 1))
290 // after half clock period of driving the sda low, the only possible
291 // transition is to send state.
292 // if send bit is not active, stop the procedure - undrive sda
293 if (clk_gen_cnt == period_cnt)
295 clk_gen_cnt_clr = 1'b1 ;
298 tx_rx_next_state = tx_rx_send_bits ;
304 tx_rx_next_state = tx_rx_idle ;
311 clk_gen_cnt_en = 1'b1 ;
313 // generate high to low transition on the scl line immediately
314 if (clk_gen_cnt == 'h0)
320 // after half of clock low time, load new value for sda oe, depending on the
321 // msb bit in the shift register
322 if (clk_gen_cnt == (period_cnt >> 2))
324 sda_oe = ~tx_shift_reg[7] ;
329 // after clock low time, generate low to high transition on the scl line
330 if (clk_gen_cnt == (period_cnt >> 1))
336 // after clock high time, check what to do next
337 if (clk_gen_cnt == (period_cnt))
339 clk_gen_cnt_clr = 1'b1 ;
343 // after transmiting all the bits, the only possible transition is to the state
344 // that checks the eprom acknowledge
346 tx_rx_next_state = tx_rx_rec_ack ;
351 tx_rx_next_state = tx_rx_idle ;
359 clk_gen_cnt_en = 1'b1 ;
360 sda_i_reg_en = 1'b1 ;
362 // generate high to low transition on the scl line immediately
363 if (clk_gen_cnt == 'h0)
369 // after half of clock low time, disable sda driver
370 if (clk_gen_cnt == (period_cnt >> 2))
376 // after clock low time, generate low to high transition on the scl line
377 if (clk_gen_cnt == (period_cnt >> 1))
383 // after half of clock high time, report received bit
384 if (clk_gen_cnt == ((period_cnt >> 1) + (period_cnt >> 2)) )
389 // after clock period is finished, check the next operation
390 if (clk_gen_cnt == (period_cnt))
392 clk_gen_cnt_clr = 1'b1 ;
396 // when all bits are received, only nack or ack next states are possible
398 tx_rx_next_state = tx_rx_send_ack ;
400 tx_rx_next_state = tx_rx_send_nack ;
403 tx_rx_next_state = tx_rx_idle ;
411 clk_gen_cnt_en = 1'b1 ;
413 // generate high to low transition on the scl line
414 if (clk_gen_cnt == 'h0)
420 // after half of clock low time, enable the sda driver
421 if (clk_gen_cnt == (period_cnt >> 2))
428 // after clock low time, disable the scl driver - generate low to high transition on the scl line
429 if (clk_gen_cnt == (period_cnt >> 1))
435 // after clock period time expires, check what to do next
436 if (clk_gen_cnt == period_cnt)
438 clk_gen_cnt_clr = 1'b1 ;
440 // after the byte is acknowledged, the only possible next state is receive bits
443 tx_rx_next_state = tx_rx_rec_bits ;
446 // this should never happen
450 tx_rx_next_state = tx_rx_idle ;
458 clk_gen_cnt_en = 1'b1 ;
459 sda_i_reg_en = 1'b1 ;
461 // generate high to low transition on the scl line
462 if (clk_gen_cnt == 'h0)
468 // after half of clock low time, disable the sda driver
469 if (clk_gen_cnt == (period_cnt >> 2))
475 // after clock low time, disable the scl driver - generate low to high transition on the scl line
476 if (clk_gen_cnt == (period_cnt >> 1))
482 // after 1/2 clock high time, report ack or nack condition, depending on the sda input state
483 if (clk_gen_cnt == ((period_cnt >> 1) + (period_cnt >> 2)) )
485 ack_rec = ~sda_i_reg ;
486 nack_rec = sda_i_reg ;
489 // after clock period time expires, check what to do next
490 if (clk_gen_cnt == period_cnt)
492 clk_gen_cnt_clr = 1'b1 ;
495 tx_rx_next_state = tx_rx_send_bits ;
497 tx_rx_next_state = tx_rx_rec_bits ;
499 tx_rx_next_state = tx_rx_stop ;
501 tx_rx_next_state = tx_rx_restart ;
504 // this should never happen
505 tx_rx_next_state = tx_rx_idle ;
512 clk_gen_cnt_en = 1'b1 ;
514 // generate high to low transition on the scl line
515 if (clk_gen_cnt == 'h0)
521 // after half of clock low time, disable the sda driver
522 if (clk_gen_cnt == (period_cnt >> 2))
529 // after clock low time, disable the scl driver - generate low to high transition on the scl line
530 if (clk_gen_cnt == (period_cnt >> 1))
536 // after clock period time expires, check what to do next
537 if (clk_gen_cnt == period_cnt)
539 clk_gen_cnt_clr = 1'b1 ;
541 // after the no acknowledge is sent, the only possible next state is stop
544 tx_rx_next_state = tx_rx_stop ;
547 // this should never happen
548 tx_rx_next_state = tx_rx_idle ;
555 clk_gen_cnt_en = 1'b1 ;
557 // generate high to low transition
558 if (clk_gen_cnt == 'h0)
564 // after half of clock low time, release sda line
565 if (clk_gen_cnt == (period_cnt >> 2))
571 // generate low to high transition
572 if (clk_gen_cnt == (period_cnt >> 1))
574 clk_gen_cnt_clr = 1'b1 ;
580 tx_rx_next_state = tx_rx_start ;
582 tx_rx_next_state = tx_rx_idle ;
588 clk_gen_cnt_en = 1'b1 ;
590 // generate high to low transition
591 if (clk_gen_cnt == 'h0)
597 // after half of clock low time, drive sda line low
598 if (clk_gen_cnt == (period_cnt >> 2))
604 // generate low to high transition
605 if (clk_gen_cnt == (period_cnt >> 1))
611 // after full clock period, release the sda line
612 if (clk_gen_cnt == period_cnt)
618 tx_rx_next_state = tx_rx_idle ;
625 reg [rw_seq_state_width - 1:0] rw_seq_state ;
632 reg [ 3: 0] bits_transfered ;
634 always@(posedge clk_i or posedge reset_i)
638 rw_seq_state <= rw_seq_idle ;
641 doing_write <= 1'b0 ;
642 doing_seq_read <= 1'b0 ;
644 tx_shift_reg <= 'h0 ;
651 bits_transfered <= 'h0 ;
652 write_done_o <= 'h0 ;
664 tx_shift_reg <= {4'b1010, adr_i[10: 8], 1'b0} ;
667 if ( tx_rx_sm_idle & ~(doing_write | doing_read | doing_seq_read) )
669 if (do_write_i | do_rnd_read_i | do_seq_read_i)
671 rw_seq_state <= rw_seq_tx_ctrl ;
676 doing_write <= 1'b1 ;
677 else if (do_rnd_read_i)
679 else if (do_seq_read_i)
680 doing_seq_read <= 1'b1 ;
684 doing_write <= 1'b0 ;
686 doing_seq_read <= 1'b0 ;
694 bits_transfered <= 'h0 ;
706 bits_transfered <= bits_transfered + 1'b1 ;
707 tx_shift_reg <= {tx_shift_reg[6:0], tx_shift_reg[0]} ;
710 if (bits_transfered == 'h8)
718 bits_transfered <= 'h0 ;
720 if (ack_rec | nack_rec)
725 if (doing_write | ~adr_set)
727 rw_seq_state <= rw_seq_tx_adr ;
728 tx_shift_reg <= adr_i[ 7: 0] ;
733 rw_seq_state <= rw_seq_rx_byte ;
750 rw_seq_state <= rw_seq_idle ;
761 bits_transfered <= bits_transfered + 1'b1 ;
762 tx_shift_reg <= {tx_shift_reg[6:0], tx_shift_reg[0]} ;
765 if (bits_transfered == 'h8)
773 bits_transfered <= 'h0 ;
775 if (ack_rec | nack_rec)
786 rw_seq_state <= rw_seq_tx_byte ;
787 tx_shift_reg <= dat_i ;
789 else if (doing_read | doing_seq_read)
792 rw_seq_state <= rw_seq_tx_ctrl ;
793 tx_shift_reg <= 8'b10100001 ;
809 rw_seq_state <= rw_seq_idle ;
820 bits_transfered <= bits_transfered + 1'b1 ;
821 tx_shift_reg <= {tx_shift_reg[6:0], tx_shift_reg[0]} ;
824 if (bits_transfered == 'h8)
832 bits_transfered <= 'h0 ;
834 if (ack_rec | nack_rec)
844 write_done_o <= 1'b1 ;
849 write_done_o <= 1'b0 ;
854 rw_seq_state <= rw_seq_idle ;
865 bits_transfered <= bits_transfered + 1'b1 ;
866 dat_o <= {dat_o[6:0], sda_i_reg} ;
869 if (bits_transfered == 'h8)
882 bits_transfered <= 'h0 ;
893 bits_transfered <= 'h0 ;
911 rw_seq_state <= rw_seq_idle ;
919 endmodule // pci_spoci_ctrl