source: PlatformSupport/CustomPeripherals/pcores/w3_clock_controller_axi_v4_00_a/hdl/verilog/at_boot_clk_config.v

Last change on this file was 4303, checked in by murphpo, 9 years ago

More pipeline regs in picoblaze periph connections

File size: 9.0 KB
Line 
1module at_boot_clk_config (
2
3    input clk,
4    input clk_valid,
5    input pll_refclk,
6
7    output [3:0] leds_red,
8    output reg [3:0] leds_green,
9
10    input  [2:0] cm_switch,
11
12    output uart_tx,
13   
14    input  iic_eeprom_scl_I,
15    output iic_eeprom_scl_O,
16    output iic_eeprom_scl_T,
17
18    input  iic_eeprom_sda_I,
19    output iic_eeprom_sda_T,
20    output iic_eeprom_sda_O,
21   
22    output reg samp_spi_sclk,
23    output reg samp_spi_mosi,
24    output reg samp_spi_cs_n = 1,
25   
26    output reg rfref_spi_sclk,
27    output reg rfref_spi_mosi,
28    output reg rfref_spi_cs_n = 1,
29   
30    output reg cm_spi_sclk,
31    output reg cm_spi_mosi,
32    output reg cm_spi_cs_n = 1,
33
34    input cm_pll_status,
35   
36    output reg clk_config_done = 0
37);
38
39wire    [11:0]  pb_address;
40wire    [17:0]  pb_instruction;
41wire            pb_bram_enable;
42wire    [7:0]   pb_io_port_id;
43wire    [7:0]   pb_out_port;
44reg     [7:0]   pb_in_port;
45wire            pb_out_write_en;
46wire            pb_k_write_strobe;
47wire            pb_in_read_en;
48wire            pb_sleep;
49wire            pb_reset;
50wire            pb_bram_rdl;
51
52wire [7:0]  pb_uart_tx_byte;
53wire        pb_uart_tx_wr_en;
54wire        pb_uart_tx_data_rdy;
55wire        pb_uart_tx_half_full;
56wire        pb_uart_tx_full;
57reg         pb_uart_tx_reset;
58
59reg         pb_iic_scl_drive_low;
60reg         pb_iic_sda_drive_low;
61
62reg [6:0]   pb_uart_clk16_cnt;
63reg         pb_uart_clk16_en;
64
65reg cm_pll_status_d;
66reg [2:0] cm_switch_d;
67
68reg serial_data_mosi;
69
70wire pll_refclk_valid;//TODO
71reg pll_refclk_mon_en;
72
73reg [7:0] pb_uart_tx_byte_d1;
74reg       pb_uart_tx_wr_en_d1;
75
76
77//Register inputs
78always @(posedge clk)
79begin
80    cm_pll_status_d <= cm_pll_status;
81    cm_switch_d <= cm_switch;
82end
83
84// PicoBlaze CPU
85kcpsm6 #(
86    .interrupt_vector       (12'h3FF),
87    .scratch_pad_memory_size(128),
88    .hwbuild                (8'h00)
89) picoblaze_cpu (
90    .address        (pb_address),
91    .instruction    (pb_instruction),
92    .bram_enable    (pb_bram_enable),
93    .port_id        (pb_io_port_id),
94    .write_strobe   (pb_out_write_en),
95    .k_write_strobe (pb_k_write_strobe),
96    .out_port       (pb_out_port),
97    .read_strobe    (pb_in_read_en),
98    .in_port        (pb_in_port),
99    .interrupt      (1'b0),
100    .interrupt_ack  (),
101    .reset          (pb_reset),
102    .sleep          (pb_sleep),
103    .clk            (clk)
104); 
105
106// Picoblaze program ROM
107//leds_only #(
108prog_clk_config_boot #(
109    .C_FAMILY               ("V6"),     //Family 'S6' or 'V6'
110    .C_RAM_SIZE_KWORDS      (2),        //Program size '1', '2' or '4'
111    .C_JTAG_LOADER_ENABLE   (0)         //Include JTAG Loader when set to 1'b1
112) program_rom (                         //Name to match your PSM file
113    .rdl            (pb_bram_rdl),
114    .enable         (pb_bram_enable),
115    .address        (pb_address),
116    .instruction    (pb_instruction),
117    .clk            (clk)
118);
119
120//Hold PicoBlaze in reset until clk is valid
121// clk_valid tied to MMCM.locked in XPS design
122assign pb_reset = pb_bram_rdl || (~clk_valid);
123
124//PicoBlaze UART Tx module
125uart_tx6 pb_uart_tx (
126    .data_in(pb_uart_tx_byte_d1),
127    .en_16_x_baud(pb_uart_clk16_en),
128    .serial_out(uart_tx),
129    .buffer_write(pb_uart_tx_wr_en_d1),
130    .buffer_data_present(pb_uart_tx_data_rdy),
131    .buffer_half_full(pb_uart_tx_half_full),
132    .buffer_full(pb_uart_tx_full),
133    .buffer_reset(pb_uart_tx_reset),             
134    .clk(clk)
135);
136
137// Mux for PicoBlaze input port
138//  Port 0: Tx UART Status
139//      P0[2]: pb_uart_tx_full
140//      P0[1]: pb_uart_tx_half_full
141//      P0[0]: pb_uart_tx_data_rdy
142//  Port 1: SPI Inputs
143//      P1[2]: Clock module PLL MISO
144//      P1[1]: RF ref clk buffer MISO
145//      P1[0]: Samp clk buffer MISO
146//  Port 2: Clock module config/status
147//      P2[4]: Ref clock valid
148//      P2[3]: PLL locked
149//      P2[2]: CM switch[2] (CM-PLL) or 1'b1 (CM-MMCX)
150//      P2[1]: CM switch[1]
151//      P2[0]: CM switch[0]
152//  Port 3: I2C inputs
153//      P3[0]: IIC SCL input (.O of IOBUFT for SCL in/out)
154//      P3[1]: IIC SDA input (.O of IOBUFT for SDA in/out)
155always @ (posedge clk)
156begin
157    case (pb_io_port_id[1:0]) 
158        2'b00 : pb_in_port <= { 5'b0, pb_uart_tx_full, pb_uart_tx_half_full, pb_uart_tx_data_rdy};
159        2'b01 : pb_in_port <= { 8'b0 };
160        2'b10 : pb_in_port <= { 3'b0, pll_refclk_valid, cm_pll_status_d, cm_switch_d[2:0]};
161        2'b11 : pb_in_port <= { 6'b0, iic_eeprom_sda_I, iic_eeprom_scl_I};
162        default : pb_in_port <= 8'bXXXXXXXX ; 
163    endcase
164end
165
166/*
167Decode for PicoBlaze output port
168  Some output writes use OUTPUTK instruction. HDL must monitor k_write_strobe and write_en
169  SPI slave devices must honor their chip selects to ignore clock/data assertions when not selected.
170  SPI chip select signals from PicoBlaze are active high (1=chip selected). HDL must invert for active-low outputs.
171  PicoBlaze only asserts "drive low" signal for IIC clock/data. IOBUFT.I must be tied to net_gnd.
172
173    Port 0: UART Tx
174        P0[7:0]: Byte to transmit
175
176    Port 1: SPI clocks
177        P1[0]: Samp clk buffer SPI clk
178        P1[1]: RF ref clk buffer SPI clk
179        P1[2]: Clock mod PLL SPI clk
180
181    Port 2: SPI serial data out
182        P2[7]: SPI MOSI - should be shared by all slaves
183
184    Port 3: SPI chip selects
185        P3[0]: Samp clk buffer SPI chip select (active high)
186        P3[1]: RF ref clk buffer SPI chip select (active high)
187        P3[2]: Clock mod PLL SPI chip select (active high)
188
189    Port 4: IIC clock/data
190        P4[0]: Drive IIC SCL output low
191        P4[1]: Drive IIC SDA output low
192
193    Port 5: LEDs
194        P4[3:0]: Green LEDs
195        P4[7:4]: Red LEDs
196
197    Port 6: Status/control
198        P5[0]: Program done - allow MMCMs to start and MicroBlazes to boot
199        P5[1]: Enable PLL ref clock monitor
200        P5[2]: Reset UART Tx core
201*/
202
203// Decode output port 0 for UART Tx; add pipeline reg before UART core for better timing
204assign pb_uart_tx_byte = pb_out_port;
205assign pb_uart_tx_wr_en = ((pb_k_write_strobe == 1'b1) || (pb_out_write_en == 1'b1)) & (pb_io_port_id[2:0] == 3'd0);
206
207always @(posedge clk)
208begin
209    pb_uart_tx_byte_d1 <= pb_uart_tx_byte;
210    pb_uart_tx_wr_en_d1 <= pb_uart_tx_wr_en;
211end
212
213// Decode other ports
214always @ (posedge clk)
215begin
216    if ( (pb_k_write_strobe == 1'b1) || (pb_out_write_en == 1'b1) )
217    begin
218        if (pb_io_port_id[2:0] == 3'd1)
219        begin
220            samp_spi_sclk   <= pb_out_port[0];
221            rfref_spi_sclk  <= pb_out_port[1];
222            cm_spi_sclk     <= pb_out_port[2];
223        end
224        else if(pb_io_port_id[2:0] == 3'd2)
225        begin
226            serial_data_mosi    <= pb_out_port[7];
227        end
228        else if(pb_io_port_id[2:0] == 3'd3)
229        begin
230            samp_spi_cs_n   <= ~pb_out_port[0]; //AD9512 chip select is active low
231            rfref_spi_cs_n  <= ~pb_out_port[1]; //AD9512 chip select is active low
232            cm_spi_cs_n     <= ~pb_out_port[2]; //AD9511 chip select is active low
233        end
234        else if (pb_io_port_id[2:0] == 3'd4)
235        begin
236            pb_iic_scl_drive_low <= pb_out_port[0];
237            pb_iic_sda_drive_low <= pb_out_port[1];
238        end
239        else if (pb_io_port_id[2:0] == 3'd5)
240        begin
241            leds_green[3:0] <= pb_out_port[3:0];
242            //leds_red[3:0]     <= pb_out_port[7:4];
243        end
244        else if (pb_io_port_id[2:0] == 3'd6)
245        begin
246            clk_config_done     <= pb_out_port[0];
247            pll_refclk_mon_en   <= pb_out_port[1];
248            pb_uart_tx_reset    <= pb_out_port[2];
249        end
250    end
251end
252
253//Duplicate common SPI MOSI signal to all outputs
254always @(posedge clk)
255begin
256    samp_spi_mosi <= serial_data_mosi;
257    rfref_spi_mosi <= serial_data_mosi;
258    cm_spi_mosi <= serial_data_mosi;
259end
260
261//Perma-sleep PicoBlaze when its program completes
262// This register will stay asserted until the FPGA is re-configured
263reg clk_config_done_d1 = 0;
264assign pb_sleep = clk_config_done_d1;
265always @(posedge clk)
266    clk_config_done_d1 <= clk_config_done;
267
268//Generate UART clock (~16x serial port data rate)
269// pb_uart_clk16_cnt == 108 for 200MHz clk, UART @ 115200
270always @ (posedge clk)
271begin
272    if (pb_uart_clk16_cnt >= 108)  //200MHz/108/16 ~ 115k
273    begin
274        pb_uart_clk16_cnt <= 0;
275        pb_uart_clk16_en <= 1'b1;
276    end
277    else
278    begin
279        pb_uart_clk16_cnt <= pb_uart_clk16_cnt + 1;
280        pb_uart_clk16_en <= 1'b0;
281    end
282end
283
284//IOBUFT signals for I2C pins; actual IOBUFT are implemented above
285// this module to allow muxing with other IIC controller in XPS design
286assign iic_eeprom_scl_T = pb_iic_scl_drive_low;
287assign iic_eeprom_scl_O = 1'b0;
288
289assign iic_eeprom_sda_T = pb_iic_sda_drive_low;
290assign iic_eeprom_sda_O = 1'b0;
291
292
293//PLL ref clock monitor
294reg [11:0] pll_refclk_mon_cnt = 0;
295reg [7:0]  pll_refclk_mon_timeout_cnt = 0;
296reg pll_refclk_mon_timeout_reset;
297wire pll_refclk_mon_timeout;
298
299always @(posedge clk)
300begin
301    if(pll_refclk_mon_timeout_reset || pll_refclk_valid || ~pll_refclk_mon_en)
302        pll_refclk_mon_timeout_cnt <= 8'h00;
303    else if(clk_valid)
304        pll_refclk_mon_timeout_cnt <= pll_refclk_mon_timeout_cnt + 1;
305end
306
307assign pll_refclk_mon_timeout = (pll_refclk_mon_timeout_cnt == 8'hFF);
308
309wire pll_refclk_mon_reset;
310assign pll_refclk_mon_reset = (~pll_refclk_mon_en || pll_refclk_mon_timeout);
311
312always @(posedge pll_refclk or posedge pll_refclk_mon_reset)
313begin
314    if(pll_refclk_mon_reset)
315    begin
316        pll_refclk_mon_cnt <= 12'h000;
317        pll_refclk_mon_timeout_reset <= 1'b0;
318    end
319    else if(pll_refclk_mon_cnt < 12'hFFF)
320    begin
321        pll_refclk_mon_cnt <= pll_refclk_mon_cnt + 1;
322        pll_refclk_mon_timeout_reset <= 1'b1;
323    end
324    else
325    begin
326        pll_refclk_mon_cnt <= pll_refclk_mon_cnt;
327        pll_refclk_mon_timeout_reset <= 1'b0;
328    end
329end
330assign leds_red = pll_refclk_mon_cnt[3:0];
331
332assign pll_refclk_valid = (pll_refclk_mon_cnt == 12'hFFF);
333
334endmodule
Note: See TracBrowser for help on using the repository browser.