Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module dsp_core
- #(
- parameter adc_width = 12,
- parameter device_ID = 24'b111100001100110010101011, // test pattern by default, change to real ID in project settings (F0CCAB)
- parameter rst_cycles = 4,
- parameter meas_points = 4096,
- localparam max_meas_points = 4096,
- localparam rst_cyc_cnt = $clog2(rst_cycles),
- localparam max_meas_pnt_cnt = $clog2(max_meas_points)
- )
- (
- // For testing (comment out PLL and same name signals)
- //input hs_clk,
- //input ms_clk,
- //input pll_lock,
- // main clock
- input sys_clk,
- input rst,
- // SPI for data output
- input sck,
- input ncs,
- output so,
- input si,
- // Current measurement/calculation done
- output meas_done,
- // ADC inputs
- output adc_clk,
- input adc_conv_clk,
- input [adc_width-1:0] adc_a,
- input [adc_width-1:0] adc_b
- );
- // Wires and registry
- reg global_rst, spi_rst;
- reg [rst_cyc_cnt-1:0] g_rst_c;
- wire pll_lock;
- wire hs_clk; // 250 MHz - High speed clock
- wire ms_clk; // 125 MHz - Medium speed clock (this can either be divided by 2 to get 62.5 MHz clock signal (for ADC), or we can simply route out the low speed clock)
- reg ls_clk; // 62.5 MHz - Low speed clock
- // SPI Control
- wire spi_rw_ready, spi_addr_rdy, spi_data_rdy;
- wire [6:0] spi_addr; // 7 bit address
- wire spi_rw; // 1 is read 0 is write
- wire [23:0] spi_data; // 24 bit data
- reg [23:0] spi_data_tx; // 24 bit data - must be ready within 1 serial clock cycle
- // ADC FIFO Data Signals
- wire [2*adc_width-1 : 0] adc_ab = {adc_a, adc_b};
- wire [2*adc_width-1 : 0] spi_ab;
- // FIFO Control Signals
- reg fifo_clear;
- reg fifo_wr_en, fifo_rd_en;
- wire fifo_full, fifo_empty;
- wire busy = fifo_wr_en | fifo_rd_en;
- wire ram_clock = fifo_wr_en ? (~adc_conv_clk) : spi_rw;
- pll_core PLL(
- .ref_clk_i(sys_clk),
- .rst_n_i(~rst),
- .lock_o(pll_lock),
- .outcore_o( ),
- .outglobal_o(hs_clk),
- .outcoreb_o( ),
- .outglobalb_o(ms_clk)
- );
- soft_spi_slave SPI(
- // Global signals
- .rst(spi_rst),
- // SPI interface
- .sck(sck),
- .ncs(ncs),
- .so(so),
- .si(si),
- // Internal signals
- .addr(spi_addr),
- .addr_ready(spi_addr_rdy),
- .rw(spi_rw),
- .rw_ready(spi_rw_ready),
- .data_out(spi_data),
- .data_ready(spi_data_rdy),
- .data_in(spi_ab)
- );
- reg [11:0] test_c;
- always @ (negedge adc_conv_clk) begin
- if (global_rst)
- test_c <= 0;
- else
- test_c <= test_c + 1;
- end
- wire [23:0] test_cw = {test_c, test_c};
- fifo #(
- .max_data_count(4)
- ) meas_fifo (
- .rst(global_rst || fifo_clear),
- .write_en(fifo_wr_en),
- .wclk(adc_conv_clk),
- //.din(adc_ab),
- .din(test_cw),
- //.din(device_ID),
- .rclk(spi_rw),
- .dout(spi_ab),
- .full(fifo_full),
- .empty(fifo_empty),
- .direction()
- );
- // Get rising PLL lock signal edge (so we can reset logic internally)
- reg [1:0] lock_r; always @(posedge ms_clk) lock_r <= {lock_r[0], pll_lock};
- wire lock_rising = lock_r[1:0] == 2'b01;
- // Sync RST and get edges
- reg [1:0] rst_r; always @(posedge ms_clk) rst_r <= {rst_r[0], rst};
- wire rst_rising = rst_r[1:0] == 2'b01;
- wire rst_falling = rst_r[1:0] == 2'b10;
- // Clock dividers
- always @ (posedge ms_clk) begin
- if (global_rst) begin
- ls_clk <= 0;
- end else begin
- ls_clk <= ~ls_clk;
- end
- end
- // Detect ADDR ready edge
- reg [1:0] addr_rdy_r;
- wire addr_rdy_rising = addr_rdy_r[1:0] == 2'b01;
- wire addr_rdy_falling = addr_rdy_r[1:0] == 2'b10;
- reg addr_rdy_rising_d;
- always @(posedge ms_clk) begin
- if (global_rst) begin
- addr_rdy_r <= 2'b00;
- addr_rdy_rising_d <= 0;
- end else begin
- addr_rdy_r <= {addr_rdy_r[0], spi_addr_rdy};
- addr_rdy_rising_d <= addr_rdy_rising;
- end
- end
- // Registry handling
- always @ (posedge ms_clk) begin
- // Reset signal handling
- if (rst_rising || lock_rising) begin
- global_rst <= 1;
- g_rst_c <= 0;
- end else begin
- if (g_rst_c == (rst_cycles - 1))
- global_rst <= 0;
- end
- if (global_rst) begin
- // RAM control registry
- fifo_clear <= 0;
- fifo_wr_en <= 0;
- fifo_rd_en <= 0;
- // Increment extended reset counters
- g_rst_c <= g_rst_c + 1;
- end else begin
- if (addr_rdy_rising) begin
- if (spi_rw) begin
- fifo_wr_en <= 0;
- fifo_rd_en <= 1;
- end else begin
- fifo_clear <= 1;
- fifo_rd_en <= 0;
- fifo_wr_en <= 1;
- end
- end
- if (addr_rdy_rising_d) begin
- if (!spi_rw) begin
- fifo_clear <= 0;
- end
- end
- if (fifo_full) fifo_wr_en <= 0;
- if (fifo_empty) fifo_rd_en <= 0;
- end
- end
- // This output is used as a "busy" signal
- assign meas_done = busy;
- // Use the B output /2 clock for the ADC conversion
- assign adc_clk = ls_clk;
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement