1// -*- verilog -*-
2//
3//  USRP - Universal Software Radio Peripheral
4//
5//  Copyright (C) 2003,2004 Matt Ettus
6//
7//  This program is free software; you can redistribute it and/or modify
8//  it under the terms of the GNU General Public License as published by
9//  the Free Software Foundation; either version 2 of the License, or
10//  (at your option) any later version.
11//
12//  This program is distributed in the hope that it will be useful,
13//  but WITHOUT ANY WARRANTY; without even the implied warranty of
14//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15//  GNU General Public License for more details.
16//
17//  You should have received a copy of the GNU General Public License
18//  along with this program; if not, write to the Free Software
19//  Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
20//
21
22
23
24// Serial Control Bus from Cypress chip
25
26module serial_io
27  ( input master_clk,
28    input serial_clock,
29    input serial_data_in,
30    input enable,
31    input reset,
32    inout wire serial_data_out,
33    output reg [6:0] serial_addr,
34    output reg [31:0] serial_data,
35    output wire serial_strobe,
36    input wire [31:0] readback_0,
37    input wire [31:0] readback_1,
38    input wire [31:0] readback_2,
39    input wire [31:0] readback_3,
40    input wire [31:0] readback_4,
41    input wire [31:0] readback_5,
42    input wire [31:0] readback_6,
43    input wire [31:0] readback_7
44    );
45
46   reg 	      is_read;
47   reg [7:0]  ser_ctr;
48   reg 	      write_done;
49
50   assign serial_data_out = is_read ? serial_data[31] : 1'bz;
51
52   always @(posedge serial_clock, posedge reset, negedge enable)
53     if(reset)
54       ser_ctr <= #1 8'd0;
55     else if(~enable)
56       ser_ctr <= #1 8'd0;
57     else if(ser_ctr == 39)
58       ser_ctr <= #1 8'd0;
59     else
60       ser_ctr <= #1 ser_ctr + 8'd1;
61
62   always @(posedge serial_clock, posedge reset, negedge enable)
63     if(reset)
64       is_read <= #1 1'b0;
65     else if(~enable)
66       is_read <= #1 1'b0;
67     else if((ser_ctr == 7)&&(serial_addr[6]==1))
68       is_read <= #1 1'b1;
69
70   always @(posedge serial_clock, posedge reset)
71     if(reset)
72       begin
73	  serial_addr <= #1 7'b0;
74	  serial_data <= #1 32'b0;
75	  write_done <= #1 1'b0;
76       end
77     else if(~enable)
78       begin
79	  //serial_addr <= #1 7'b0;
80	  //serial_data <= #1 32'b0;
81	  write_done <= #1 1'b0;
82       end
83     else
84       begin
85	  if(~is_read && (ser_ctr == 39))
86	    write_done <= #1 1'b1;
87	  else
88	    write_done <= #1 1'b0;
89	  if(is_read & (ser_ctr==8))
90	    case (serial_addr)
91	      7'd1: serial_data <= #1 readback_0;
92	      7'd2: serial_data <= #1 readback_1;
93	      7'd3: serial_data <= #1 readback_2;
94	      7'd4: serial_data <= #1 readback_3;
95	      7'd5: serial_data <= #1 readback_4;
96	      7'd6: serial_data <= #1 readback_5;
97	      7'd7: serial_data <= #1 readback_6;
98	      7'd8: serial_data <= #1 readback_7;
99	      default: serial_data <= #1 32'd0;
100	    endcase // case(serial_addr)
101	  else if(ser_ctr >= 8)
102	    serial_data <= #1 {serial_data[30:0],serial_data_in};
103	  else if(ser_ctr < 8)
104	    serial_addr <= #1 {serial_addr[5:0],serial_data_in};
105       end // else: !if(~enable)
106
107   reg enable_d1, enable_d2;
108   always @(posedge master_clk)
109     begin
110	enable_d1 <= #1 enable;
111	enable_d2 <= #1 enable_d1;
112     end
113
114   assign serial_strobe = enable_d2 & ~enable_d1;
115
116endmodule // serial_io
117
118
119