Advertisement
MysteriousWolf

core.v

Oct 31st, 2024
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VeriLog 4.72 KB | Source Code | 0 0
  1. module dsp_core
  2. #(
  3.     parameter adc_width = 12,
  4.     parameter device_ID = 24'b111100001100110010101011, // test pattern by default, change to real ID in project settings (F0CCAB)
  5.     parameter rst_cycles = 4,
  6.     parameter meas_points = 4096,
  7.     localparam max_meas_points = 4096,
  8.     localparam rst_cyc_cnt = $clog2(rst_cycles),
  9.     localparam max_meas_pnt_cnt = $clog2(max_meas_points)
  10. )
  11. (
  12.     // For testing (comment out PLL and same name signals)
  13.     //input hs_clk,
  14.     //input ms_clk,
  15.     //input pll_lock,
  16.    
  17.     // main clock
  18.     input sys_clk,
  19.     input rst,
  20.    
  21.     // SPI for data output
  22.     input sck,
  23.     input ncs,
  24.     output so,
  25.     input si,
  26.    
  27.     // Current measurement/calculation done
  28.     output meas_done,
  29.    
  30.     // ADC inputs
  31.     output adc_clk,
  32.     input adc_conv_clk,
  33.     input [adc_width-1:0] adc_a,
  34.     input [adc_width-1:0] adc_b
  35. );
  36.     // Wires and registry
  37.     reg global_rst, spi_rst;
  38.     reg [rst_cyc_cnt-1:0] g_rst_c;
  39.     wire pll_lock;
  40.     wire hs_clk;        // 250 MHz - High speed clock
  41.     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)
  42.     reg ls_clk;         // 62.5 MHz - Low speed clock
  43.    
  44.     // SPI Control
  45.     wire        spi_rw_ready, spi_addr_rdy, spi_data_rdy;
  46.     wire [6:0]  spi_addr;       // 7 bit address
  47.     wire        spi_rw;         // 1 is read 0 is write
  48.     wire [23:0] spi_data;       // 24 bit data
  49.     reg [23:0]  spi_data_tx;    // 24 bit data - must be ready within 1 serial clock cycle
  50.    
  51.     // ADC FIFO Data Signals
  52.     wire [2*adc_width-1 : 0] adc_ab = {adc_a, adc_b};
  53.     wire [2*adc_width-1 : 0] spi_ab;
  54.    
  55.     // FIFO Control Signals
  56.     reg fifo_clear;
  57.     reg fifo_wr_en, fifo_rd_en;
  58.     wire fifo_full, fifo_empty;
  59.     wire busy = fifo_wr_en | fifo_rd_en;
  60.     wire ram_clock = fifo_wr_en ? (~adc_conv_clk) : spi_rw;
  61.    
  62.     pll_core PLL(
  63.         .ref_clk_i(sys_clk),
  64.         .rst_n_i(~rst),
  65.         .lock_o(pll_lock),
  66.         .outcore_o( ),
  67.         .outglobal_o(hs_clk),
  68.         .outcoreb_o( ),
  69.         .outglobalb_o(ms_clk)
  70.     );
  71.        
  72.     soft_spi_slave SPI(
  73.         // Global signals
  74.         .rst(spi_rst),
  75.        
  76.         // SPI interface
  77.         .sck(sck),
  78.         .ncs(ncs),
  79.         .so(so),
  80.         .si(si),
  81.        
  82.         // Internal signals
  83.         .addr(spi_addr),
  84.         .addr_ready(spi_addr_rdy),
  85.        
  86.         .rw(spi_rw),
  87.         .rw_ready(spi_rw_ready),
  88.        
  89.         .data_out(spi_data),
  90.         .data_ready(spi_data_rdy),
  91.        
  92.         .data_in(spi_ab)
  93.     );
  94.  
  95.     reg [11:0] test_c;
  96.     always @ (negedge adc_conv_clk) begin
  97.         if (global_rst)
  98.             test_c <= 0;
  99.         else
  100.             test_c <= test_c + 1;
  101.     end
  102.     wire [23:0] test_cw = {test_c, test_c};
  103.    
  104.     fifo #(
  105.         .max_data_count(4)
  106.     ) meas_fifo (
  107.         .rst(global_rst || fifo_clear),
  108.  
  109.         .write_en(fifo_wr_en),
  110.         .wclk(adc_conv_clk),
  111.         //.din(adc_ab),
  112.         .din(test_cw),
  113.         //.din(device_ID),
  114.  
  115.         .rclk(spi_rw),
  116.         .dout(spi_ab),
  117.  
  118.         .full(fifo_full),
  119.         .empty(fifo_empty),
  120.         .direction()
  121.     );
  122.    
  123.     // Get rising PLL lock signal edge (so we can reset logic internally)
  124.     reg [1:0] lock_r; always @(posedge ms_clk) lock_r <= {lock_r[0], pll_lock};
  125.     wire lock_rising = lock_r[1:0] == 2'b01;
  126.    
  127.     // Sync RST and get edges
  128.     reg [1:0] rst_r; always @(posedge ms_clk) rst_r <= {rst_r[0], rst};
  129.     wire rst_rising = rst_r[1:0] == 2'b01;
  130.     wire rst_falling = rst_r[1:0] == 2'b10;
  131.    
  132.     // Clock dividers
  133.     always @ (posedge ms_clk) begin
  134.         if (global_rst) begin
  135.             ls_clk <= 0;
  136.         end else begin
  137.             ls_clk <= ~ls_clk;
  138.         end
  139.     end
  140.    
  141.     // Detect ADDR ready edge
  142.     reg [1:0] addr_rdy_r;
  143.     wire addr_rdy_rising = addr_rdy_r[1:0] == 2'b01;
  144.     wire addr_rdy_falling = addr_rdy_r[1:0] == 2'b10;
  145.     reg addr_rdy_rising_d;
  146.     always @(posedge ms_clk) begin
  147.         if (global_rst) begin
  148.             addr_rdy_r <= 2'b00;
  149.             addr_rdy_rising_d <= 0;
  150.         end else begin
  151.             addr_rdy_r <= {addr_rdy_r[0], spi_addr_rdy};
  152.             addr_rdy_rising_d <= addr_rdy_rising;
  153.         end
  154.     end
  155.    
  156.     // Registry handling   
  157.     always @ (posedge ms_clk) begin
  158.         // Reset signal handling
  159.         if (rst_rising || lock_rising) begin
  160.             global_rst <= 1;
  161.             g_rst_c <= 0;
  162.         end else begin
  163.             if (g_rst_c == (rst_cycles - 1))
  164.                 global_rst <= 0;
  165.         end
  166.        
  167.         if (global_rst) begin
  168.             // RAM control registry
  169.             fifo_clear <= 0;
  170.             fifo_wr_en <= 0;
  171.             fifo_rd_en <= 0;
  172.            
  173.             // Increment extended reset counters
  174.             g_rst_c <= g_rst_c + 1;
  175.         end else begin
  176.             if (addr_rdy_rising) begin
  177.                 if (spi_rw) begin
  178.                     fifo_wr_en <= 0;
  179.                     fifo_rd_en <= 1;
  180.                 end else begin
  181.                     fifo_clear <= 1;
  182.                     fifo_rd_en <= 0;
  183.                     fifo_wr_en <= 1;
  184.                 end
  185.             end
  186.             if (addr_rdy_rising_d) begin
  187.                 if (!spi_rw) begin
  188.                     fifo_clear <= 0;
  189.                 end
  190.             end
  191.            
  192.             if (fifo_full) fifo_wr_en <= 0;
  193.             if (fifo_empty) fifo_rd_en <= 0;
  194.         end
  195.     end
  196.    
  197.     // This output is used as a "busy" signal
  198.     assign meas_done = busy;
  199.    
  200.     // Use the B output /2 clock for the ADC conversion
  201.     assign adc_clk = ls_clk;
  202. endmodule
Tags: FPGA
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement