red_pitaya_top.sv (v0.94_250) modification for GPIO usage

dedicated to the FPGA topics for all Red Pitaya programmers
Post Reply
sbenjamin
Posts: 10
Joined: Sun Apr 09, 2023 7:22 am

red_pitaya_top.sv (v0.94_250) modification for GPIO usage

Post by sbenjamin » Sun Dec 24, 2023 12:56 pm

Hello,

I was wondering if anyone can throw me a bone here...?

I've successfully managed to implement a "LED Blink controller" on my Red Pitaya's SIGNAL lab 250-12's FPGA, which essentially a C++ Console App which sends the LED index to blink (utilizing the write register 0x40300058 and calling the monitor command via SSH connection).

My goal is to implement a Pulse/TTL Sequencer which will use the Digital Output pins of the Red Pitaya.

I'm fairly new to FPGA programming and I am struggling to understand what modifications must I do to my "red_pitaya_top.sv" module in order to call my new modules for setting up and running my pulse sequencer program. I was told that it is as straight forward as the modifications I did for controlling the LEDs.

Can anyone take a look at my red_pitaya_top.sv module and tell me which lines to comment out, which lines to add and how does the mapping go as far as the GPIO pins on the SIGNAL lab 250-12?

Code: Select all

////////////////////////////////////////////////////////////////////////////////
// Red Pitaya TOP module. It connects external pins and PS part with
// other application modules.
// Authors: Matej Oblak, Iztok Jeras
// (c) Red Pitaya  http://www.redpitaya.com
////////////////////////////////////////////////////////////////////////////////

/**
 * GENERAL DESCRIPTION:
 *
 * Top module connects PS part with rest of Red Pitaya applications.  
 *
 *                   /-------\      
 *   PS DDR <------> |  PS   |      AXI <-> custom bus
 *   PS MIO <------> |   /   | <------------+
 *   PS CLK -------> |  ARM  |              |
 *                   \-------/              |
 *                                          |
 *                            /-------\     |
 *                         -> | SCOPE | <---+
 *                         |  \-------/     |
 *                         |                |
 *            /--------\   |   /-----\      |
 *   ADC ---> |        | --+-> |     |      |
 *            | ANALOG |       | PID | <----+
 *   DAC <--- |        | <---- |     |      |
 *            \--------/   ^   \-----/      |
 *                         |                |
 *                         |  /-------\     |
 *                         -- |  ASG  | <---+ 
 *                            \-------/     |
 *                                          |
 *             /--------\                   |
 *    RX ----> |        |                   |
 *   SATA      | DAISY  | <-----------------+
 *    TX <---- |        | 
 *             \--------/ 
 *               |    |
 *               |    |
 *               (FREE)
 *
 * Inside analog module, ADC data is translated from unsigned neg-slope into
 * two's complement. Similar is done on DAC data.
 *
 * Scope module stores data from ADC into RAM, arbitrary signal generator (ASG)
 * sends data from RAM to DAC. MIMO PID uses ADC ADC as input and DAC as its output.
 *
 * Daisy chain connects with other boards with fast serial link. Data which is
 * send and received is at the moment undefined. This is left for the user.
 */

module red_pitaya_top #(
  // identification
  bit [0:5*32-1] GITH = '0,
  // module numbers
  int unsigned MNA = 2,  // number of acquisition modules
  int unsigned MNG = 2,  // number of generator   modules
  int unsigned DWE = 9
)(
  // PS connections
  inout  logic [54-1:0] FIXED_IO_mio     ,
  inout  logic          FIXED_IO_ps_clk  ,
  inout  logic          FIXED_IO_ps_porb ,
  inout  logic          FIXED_IO_ps_srstb,
  inout  logic          FIXED_IO_ddr_vrn ,
  inout  logic          FIXED_IO_ddr_vrp ,
  // DDR
  inout  logic [15-1:0] DDR_addr   ,
  inout  logic [ 3-1:0] DDR_ba     ,
  inout  logic          DDR_cas_n  ,
  inout  logic          DDR_ck_n   ,
  inout  logic          DDR_ck_p   ,
  inout  logic          DDR_cke    ,
  inout  logic          DDR_cs_n   ,
  inout  logic [ 4-1:0] DDR_dm     ,
  inout  logic [32-1:0] DDR_dq     ,
  inout  logic [ 4-1:0] DDR_dqs_n  ,
  inout  logic [ 4-1:0] DDR_dqs_p  ,
  inout  logic          DDR_odt    ,
  inout  logic          DDR_ras_n  ,
  inout  logic          DDR_reset_n,
  inout  logic          DDR_we_n   ,

  // Red Pitaya periphery
  input  logic          trig_i ,
  input  logic          pll_ref_i,
  output logic          pll_hi_o,
  output logic          pll_lo_o,
  input  logic [ 2-1:0] temp_prot_i ,
  // ADC
  input  logic [MNA-1:0] [ 7-1:0] adc_dat_p_i,  // ADC data
  input  logic [MNA-1:0] [ 7-1:0] adc_dat_n_i,  // ADC data
  input  logic           [ 2-1:0] adc_clk_i,  // ADC clock {p,n}
  output logic                    adc_spi_csb, // ADC spi CS
  inout  logic                    adc_spi_sdio, // ADC spi DIO
  output logic                    adc_spi_clk, // ADC spi CLK
  output logic                    adc_sync_o, // ADC sync
  // DAC
  output logic [1:0][14-1:0] dac_dat_o,  // DAC combined data
  input  logic               dac_dco_i,  // DAC clock
  output logic               dac_reset_o,  // DAC reset
  output logic               dac_spi_csb, // DAC spi CS
  inout  logic               dac_spi_sdio, // DAC spi DIO
  output logic               dac_spi_clk, // DAC spi CLK
  // PWM DAC
  output logic [ 4-1:0] dac_pwm_o  ,  // 1-bit PWM DAC
  // XADC
  input  logic [ 5-1:0] vinp_i     ,  // voltages p
  input  logic [ 5-1:0] vinn_i     ,  // voltages n
  // Expansion connector
  inout  logic          exp_9_io   ,
  inout  logic [ 9-1:0] exp_p_io   ,
  inout  logic [ 9-1:0] exp_n_io   ,
  // SATA connector
  output logic [ 2-1:0] daisy_p_o  ,  // line 1 is clock capable
  output logic [ 2-1:0] daisy_n_o  ,
  input  logic [ 2-1:0] daisy_p_i  ,  // line 1 is clock capable
  input  logic [ 2-1:0] daisy_n_i  ,
  // LED
  output logic [ 8-1:0] led_o
);

////////////////////////////////////////////////////////////////////////////////
// local signals
////////////////////////////////////////////////////////////////////////////////

// GPIO input data width
localparam int unsigned GDW = 8;

logic [4-1:0] fclk ; //[0]-125MHz, [1]-250MHz, [2]-50MHz, [3]-200MHz
logic [4-1:0] frstn;
logic         idly_rdy;

logic [16-1:0] par_dat;

logic          daisy_trig;
logic [ 3-1:0] daisy_mode;
logic          trig_ext;
logic          trig_output_sel;


// AXI masters
logic            axi1_clk    , axi0_clk    ;
logic            axi1_rstn   , axi0_rstn   ;
logic [ 32-1: 0] axi1_waddr  , axi0_waddr  ;
logic [ 64-1: 0] axi1_wdata  , axi0_wdata  ;
logic [  8-1: 0] axi1_wsel   , axi0_wsel   ;
logic            axi1_wvalid , axi0_wvalid ;
logic [  4-1: 0] axi1_wlen   , axi0_wlen   ;
logic            axi1_wfixed , axi0_wfixed ;
logic            axi1_werr   , axi0_werr   ;
logic            axi1_wrdy   , axi0_wrdy   ;

// PLL signals
logic                 adc_clk_in;
logic                 pll_adc_clk;
logic                 pll_adc_clk2d;
logic                 pll_adc_10mhz;
logic                 pll_ser_clk;
logic                 pll_pwm_clk;
logic                 pll_locked;
// fast serial signals
logic                 ser_clk ;
// PWM clock and reset
logic                 pwm_clk ;
logic                 pwm_rstn;

// ADC clock/reset
logic                 adc_clk;
logic                 adc_clk2d;
logic                 adc_10mhz;
logic                 adc_rstn;

// stream bus type
localparam type SBA_T = logic signed [14-1:0];  // acquire
localparam type SBG_T = logic signed [14-1:0];  // generate


// DAC signals
logic        [14-1:0] dac_dat_a, dac_dat_b;
logic        [14-1:0] dac_a    , dac_b    ;
logic signed [15-1:0] dac_a_sum, dac_b_sum;

// ASG
SBG_T [2-1:0]            asg_dat;

// PID
SBA_T [2-1:0]            pid_dat;

// configuration
logic                    digital_loop;

logic                 adc_clk_daisy;
logic                 scope_trigo;

// system bus
sys_bus_if   ps_sys      (.clk (adc_clk2d), .rstn (adc_rstn));
sys_bus_if   sys [8-1:0] (.clk (adc_clk2d), .rstn (adc_rstn));

// GPIO interface
gpio_if #(.DW (3*GDW)) gpio ();

// SPI0
spi_if #(.DW (2)) spi0 ();

////////////////////////////////////////////////////////////////////////////////
// PLL (clock and reset)
////////////////////////////////////////////////////////////////////////////////

// diferential clock input
IBUFDS i_clk (.I (adc_clk_i[1]), .IB (adc_clk_i[0]), .O (adc_clk_in));  // differential clock input

red_pitaya_pll pll (
  // inputs
  .clk         (adc_clk_in),  // clock
  .rstn        (frstn[0]  ),  // reset - active low
  // output clocks
  .clk_adc     (pll_adc_clk   ),  // ADC clock
  .clk_adc2d   (pll_adc_clk2d ),  // ADC clock divided by 2
  .clk_10mhz   (pll_adc_10mhz ),  // ADC divided to 10MHz
  .clk_ser     (pll_ser_clk   ),  // fast serial clock
  .clk_pdm     (pll_pwm_clk   ),  // PWM clock
  // status outputs
  .pll_locked  (pll_locked)
);

BUFG bufg_adc_clk    (.O (adc_clk   ), .I (pll_adc_clk   ));
BUFG bufg_adc_clk2d  (.O (adc_clk2d ), .I (pll_adc_clk2d ));
BUFG bufg_adc_10MHz  (.O (adc_10mhz ), .I (pll_adc_10mhz ));
BUFG bufg_ser_clk    (.O (ser_clk   ), .I (pll_ser_clk   ));
BUFG bufg_pwm_clk    (.O (pwm_clk   ), .I (pll_pwm_clk   ));

logic [32-1:0] locked_pll_cnt, locked_pll_cnt_r, locked_pll_cnt_r2 ;
always @(posedge fclk[0]) begin
  if (~frstn[0])
    locked_pll_cnt <= 'h0;
  else if (~pll_locked)
    locked_pll_cnt <= locked_pll_cnt + 'h1;
end

always @(posedge adc_clk) begin
  locked_pll_cnt_r  <= locked_pll_cnt;
  locked_pll_cnt_r2 <= locked_pll_cnt_r;
end

// ADC reset (active low)
always @(posedge adc_clk2d)
adc_rstn <=  frstn[0] &  pll_locked & idly_rdy;

// PWM reset (active low)
always @(posedge pwm_clk)
pwm_rstn <=  frstn[0] &  pll_locked & idly_rdy;

always @(posedge adc_clk2d)
  daisy_trig <= |par_dat;

//assign daisy_trig = |par_dat;
assign trig_ext   = trig_i & ~(daisy_mode[0] & daisy_trig);

////////////////////////////////////////////////////////////////////////////////
//  Connections to PS
////////////////////////////////////////////////////////////////////////////////

red_pitaya_ps ps (
  .FIXED_IO_mio       (  FIXED_IO_mio                ),
  .FIXED_IO_ps_clk    (  FIXED_IO_ps_clk             ),
  .FIXED_IO_ps_porb   (  FIXED_IO_ps_porb            ),
  .FIXED_IO_ps_srstb  (  FIXED_IO_ps_srstb           ),
  .FIXED_IO_ddr_vrn   (  FIXED_IO_ddr_vrn            ),
  .FIXED_IO_ddr_vrp   (  FIXED_IO_ddr_vrp            ),
  // DDR
  .DDR_addr      (DDR_addr    ),
  .DDR_ba        (DDR_ba      ),
  .DDR_cas_n     (DDR_cas_n   ),
  .DDR_ck_n      (DDR_ck_n    ),
  .DDR_ck_p      (DDR_ck_p    ),
  .DDR_cke       (DDR_cke     ),
  .DDR_cs_n      (DDR_cs_n    ),
  .DDR_dm        (DDR_dm      ),
  .DDR_dq        (DDR_dq      ),
  .DDR_dqs_n     (DDR_dqs_n   ),
  .DDR_dqs_p     (DDR_dqs_p   ),
  .DDR_odt       (DDR_odt     ),
  .DDR_ras_n     (DDR_ras_n   ),
  .DDR_reset_n   (DDR_reset_n ),
  .DDR_we_n      (DDR_we_n    ),
  // system signals
  .fclk_clk_o    (fclk        ),
  .fclk_rstn_o   (frstn       ),
  // ADC analog inputs
  .vinp_i        (vinp_i      ),
  .vinn_i        (vinn_i      ),
  // GPIO
  .gpio          (gpio),
  // SPI0
  .spi0          (spi0),
  // system read/write channel
  .bus           (ps_sys      ),
  // AXI masters
  .axi1_clk_i    (axi1_clk    ),  .axi0_clk_i    (axi0_clk    ),  // global clock
  .axi1_rstn_i   (axi1_rstn   ),  .axi0_rstn_i   (axi0_rstn   ),  // global reset
  .axi1_waddr_i  (axi1_waddr  ),  .axi0_waddr_i  (axi0_waddr  ),  // system write address
  .axi1_wdata_i  (axi1_wdata  ),  .axi0_wdata_i  (axi0_wdata  ),  // system write data
  .axi1_wsel_i   (axi1_wsel   ),  .axi0_wsel_i   (axi0_wsel   ),  // system write byte select
  .axi1_wvalid_i (axi1_wvalid ),  .axi0_wvalid_i (axi0_wvalid ),  // system write data valid
  .axi1_wlen_i   (axi1_wlen   ),  .axi0_wlen_i   (axi0_wlen   ),  // system write burst length
  .axi1_wfixed_i (axi1_wfixed ),  .axi0_wfixed_i (axi0_wfixed ),  // system write burst type (fixed / incremental)
  .axi1_werr_o   (axi1_werr   ),  .axi0_werr_o   (axi0_werr   ),  // system write error
  .axi1_wrdy_o   (axi1_wrdy   ),  .axi0_wrdy_o   (axi0_wrdy   )   // system write ready
);



assign spi0.sck_i   = 1'b0 ;
assign spi0.ss_i    = 1'b1 ;

//reg spi0_in ;
//always @(*) begin
//  case ({spi0.ss2_o, spi0.ss1_o})
//    2'b10 : spi0_in = adc_spi_sdio ;
//    2'b01 : spi0_in = dac_spi_sdio ;
//   default: spi0_in = 1'b0 ;
//  endcase
//end

//assign adc_spi_csb   = spi0.ss1_o;
//assign adc_spi_clk   = spi0.sck_o;
//assign adc_spi_sdio  = spi0.io_t[0] ? 1'bz : spi0.io_o[0]; // MOSI <=> IO[0]
//assign dac_spi_csb   = spi0.ss2_o;
//assign dac_spi_clk   = spi0.sck_o;
//assign dac_spi_sdio  = spi0.io_t[0] ? 1'bz : spi0.io_o[0]; // MOSI <=> IO[0]

//assign spi0.io_i[1]  = spi0_in ; // MISO <=> IO[1]
//assign spi0.io_i[0]  = spi0_in ;


wire [2-1:0] hk_spi_cs  ;
wire [2-1:0] hk_spi_clk ;
wire [2-1:0] hk_spi_i   ;
wire [2-1:0] hk_spi_o   ;
wire [2-1:0] hk_spi_t   ;

assign adc_spi_csb  = hk_spi_cs[0];
assign adc_spi_clk  = hk_spi_clk[0];
assign hk_spi_i[0]  = adc_spi_sdio;
assign adc_spi_sdio = hk_spi_t[0] ? 1'bz : hk_spi_o[0] ;

assign dac_spi_csb  = hk_spi_cs[1];
assign dac_spi_clk  = hk_spi_clk[1];
assign hk_spi_i[1]  = dac_spi_sdio;
assign dac_spi_sdio = hk_spi_t[1] ? 1'bz : hk_spi_o[1] ;



////////////////////////////////////////////////////////////////////////////////
// system bus decoder & multiplexer (it breaks memory addresses into 8 regions)
////////////////////////////////////////////////////////////////////////////////

sys_bus_interconnect #(
  .SN (8),
  .SW (20)
) sys_bus_interconnect (
  .bus_m (ps_sys),
  .bus_s (sys)
);

// silence unused busses
generate
for (genvar i=6; i<8; i++) begin: for_sys
  sys_bus_stub sys_bus_stub_6_7 (sys[i]);
end: for_sys
endgenerate

////////////////////////////////////////////////////////////////////////////////
// Analog mixed signals (PDM analog outputs)
////////////////////////////////////////////////////////////////////////////////

logic [4-1:0] [8-1:0] pdm_cfg;

red_pitaya_ams i_ams (
  // power test
  .clk_i           (adc_clk2d),  // clock
  .rstn_i          (adc_rstn),  // reset - active low
  // PWM configuration
  .dac_a_o         (pdm_cfg[0]),
  .dac_b_o         (pdm_cfg[1]),
  .dac_c_o         (pdm_cfg[2]),
  .dac_d_o         (pdm_cfg[3]),
  // System bus
  .sys_addr        (sys[4].addr ),
  .sys_wdata       (sys[4].wdata),
  .sys_wen         (sys[4].wen  ),
  .sys_ren         (sys[4].ren  ),
  .sys_rdata       (sys[4].rdata),
  .sys_err         (sys[4].err  ),
  .sys_ack         (sys[4].ack  )
);

red_pitaya_pdm pdm (
  // system signals
  .clk   (adc_clk2d),
  .rstn  (adc_rstn),
  // configuration
  .cfg   (pdm_cfg),
  .ena      (1'b1),
  .rng      (8'd255),
  // PWM outputs
  .pdm (dac_pwm_o)
);



////////////////////////////////////////////////////////////////////////////////
// ADC IO
////////////////////////////////////////////////////////////////////////////////

// ADC sync is yet to drive
assign adc_sync_o = 1'bz ;

logic [2-1:0] [ 7-1:0] adc_dat_ibuf;
logic [2-1:0] [ 7-1:0] adc_dat_idly;
logic [2-1:0] [14-1:0] adc_dat_in;
logic [2-1:0] [12-1:0] adc_dat_sw;

genvar GV;
generate
for(GV = 0 ; GV < 7 ; GV = GV +1)
begin:adc_ipad
  IBUFDS i_dat0 (.I (adc_dat_p_i[0][GV]), .IB (adc_dat_n_i[0][GV]), .O (adc_dat_ibuf[0][GV]));  // differential data input
  IBUFDS i_dat1 (.I (adc_dat_p_i[1][GV]), .IB (adc_dat_n_i[1][GV]), .O (adc_dat_ibuf[1][GV]));  // differential data input
end
endgenerate

logic [2*7-1:0] idly_rst ;
logic [2*7-1:0] idly_ce  ;
logic [2*7-1:0] idly_inc ;
logic [2*7-1:0] [5-1:0] idly_cnt ;


// delay input ADC signals
//(* IODELAY_GROUP = adc_inputs *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
IDELAYCTRL i_idelayctrl (
  .RDY(idly_rdy),   // 1-bit output: Ready output
  .REFCLK(fclk[3]), // 1-bit input: Reference clock input
  .RST(!frstn[3])   // 1-bit input: Active high reset input
);


generate
for(GV = 0 ; GV < 7 ; GV = GV +1)
begin:adc_idly

   //(* IODELAY_GROUP = adc_inputs *)
   IDELAYE2 #(
      .DELAY_SRC("IDATAIN"),           // Delay input (IDATAIN, DATAIN)
      .HIGH_PERFORMANCE_MODE("TRUE"),  // Reduced jitter ("TRUE"), Reduced power ("FALSE")
      .IDELAY_TYPE("VARIABLE"),        // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
      .IDELAY_VALUE(0),                // Input delay tap setting (0-31)
      .PIPE_SEL("FALSE"),              // Select pipelined mode, FALSE, TRUE
      .REFCLK_FREQUENCY(200.0),        // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
      .SIGNAL_PATTERN("DATA")          // DATA, CLOCK input signal
   )
   i_dlya (
      .CNTVALUEOUT  ( idly_cnt[GV]          ),  // 5-bit output: Counter value output
      .DATAOUT      ( adc_dat_idly[0][GV]   ),  // 1-bit output: Delayed data output
      .C            ( adc_clk2d             ),  // 1-bit input: Clock input
      .CE           ( idly_ce[GV]           ),  // 1-bit input: Active high enable increment/decrement input
      .CINVCTRL     ( 1'b0                  ),  // 1-bit input: Dynamic clock inversion input
      .CNTVALUEIN   ( 5'h0                  ),  // 5-bit input: Counter value input
      .DATAIN       ( 1'b0                  ),  // 1-bit input: Internal delay data input
      .IDATAIN      ( adc_dat_ibuf[0][GV]   ),  // 1-bit input: Data input from the I/O
      .INC          ( idly_inc[GV]          ),  // 1-bit input: Increment / Decrement tap delay input
      .LD           ( idly_rst[GV]          ),  // 1-bit input: Load IDELAY_VALUE input
      .LDPIPEEN     ( 1'b0                  ),  // 1-bit input: Enable PIPELINE register to load data input
      .REGRST       ( 1'b0                  )   // 1-bit input: Active-high reset tap-delay input
   );

   //(* IODELAY_GROUP = adc_inputs *)
   IDELAYE2 #(
      .DELAY_SRC("IDATAIN"),           // Delay input (IDATAIN, DATAIN)
      .HIGH_PERFORMANCE_MODE("TRUE"),  // Reduced jitter ("TRUE"), Reduced power ("FALSE")
      .IDELAY_TYPE("VARIABLE"),        // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
      .IDELAY_VALUE(0),                // Input delay tap setting (0-31)
      .PIPE_SEL("FALSE"),              // Select pipelined mode, FALSE, TRUE
      .REFCLK_FREQUENCY(200.0),        // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
      .SIGNAL_PATTERN("DATA")          // DATA, CLOCK input signal
   )
   i_dlyb (
      .CNTVALUEOUT  ( idly_cnt[GV+7]        ),  // 5-bit output: Counter value output
      .DATAOUT      ( adc_dat_idly[1][GV]   ),  // 1-bit output: Delayed data output
      .C            ( adc_clk2d             ),  // 1-bit input: Clock input
      .CE           ( idly_ce[GV+7]         ),  // 1-bit input: Active high enable increment/decrement input
      .CINVCTRL     ( 1'b0                  ),  // 1-bit input: Dynamic clock inversion input
      .CNTVALUEIN   ( 5'h0                  ),  // 5-bit input: Counter value input
      .DATAIN       ( 1'b0                  ),  // 1-bit input: Internal delay data input
      .IDATAIN      ( adc_dat_ibuf[1][GV]   ),  // 1-bit input: Data input from the I/O
      .INC          ( idly_inc[GV+7]        ),  // 1-bit input: Increment / Decrement tap delay input
      .LD           ( idly_rst[GV+7]        ),  // 1-bit input: Load IDELAY_VALUE input
      .LDPIPEEN     ( 1'b0                  ),  // 1-bit input: Enable PIPELINE register to load data input
      .REGRST       ( 1'b0                  )   // 1-bit input: Active-high reset tap-delay input
   );
end
endgenerate










generate
for(GV = 0 ; GV < 14 ; GV = GV +2)
begin:adc_iddr
   IDDR #(.DDR_CLK_EDGE("SAME_EDGE_PIPELINED")) 
     i_ddr0 (.Q1(adc_dat_in[0][GV]), .Q2(adc_dat_in[0][GV+1]), .C(adc_clk), .CE(1'b1), .D(adc_dat_idly[0][GV/2]), .R(1'b0), .S(1'b0) );
   IDDR #(.DDR_CLK_EDGE("SAME_EDGE_PIPELINED")) 
     i_ddr1 (.Q1(adc_dat_in[1][GV]), .Q2(adc_dat_in[1][GV+1]), .C(adc_clk), .CE(1'b1), .D(adc_dat_idly[1][GV/2]), .R(1'b0), .S(1'b0) );
end
endgenerate



    
// data loopback
always @(posedge adc_clk)
begin
  adc_dat_sw[0] <= digital_loop ? dac_a[14-1:2] : adc_dat_in[1][14-1:2]; // switch adc_b->ch_a
  adc_dat_sw[1] <= digital_loop ? dac_b[14-1:2] : adc_dat_in[0][14-1:2]; // switch adc_a->ch_b
end

////////////////////////////////////////////////////////////////////////////////
// DAC IO
////////////////////////////////////////////////////////////////////////////////

// driving DAC reset
always @(posedge adc_clk)
  dac_reset_o <= !adc_rstn;

// Sumation of ASG and PID signal perform saturation before sending to DAC 
assign dac_a_sum = asg_dat[0] + pid_dat[0];
assign dac_b_sum = asg_dat[1] + pid_dat[1];

// saturation
assign dac_a = (^dac_a_sum[15-1:15-2]) ? {dac_a_sum[15-1], {13{~dac_a_sum[15-1]}}} :  ~dac_a_sum[14-1:0];
assign dac_b = (^dac_b_sum[15-1:15-2]) ? {dac_b_sum[15-1], {13{~dac_b_sum[15-1]}}} :  ~dac_b_sum[14-1:0];

always @(posedge adc_clk) begin
  dac_dat_a <= dac_a;
  dac_dat_b <= dac_b;
end

// IO outputs
logic dac_dco_bufg ;
BUFG bufg_dac_dco    (.O (dac_dco_bufg ), .I(dac_dco_i));

//always @(posedge dac_dco_bufg) begin
always @(posedge adc_clk) begin
  dac_dat_o[0] <= dac_dat_b ; // switch ch_b->dac_a
  dac_dat_o[1] <= dac_dat_a ; // switch ch_a->dac_b
end

////////////////////////////////////////////////////////////////////////////////
//  House Keeping
////////////////////////////////////////////////////////////////////////////////

logic [DWE-1: 0] exp_p_in , exp_n_in ;
logic [DWE-1: 0] exp_p_out, exp_n_out;
logic [DWE-1: 0] exp_p_dir, exp_n_dir;
logic [DWE-1: 0] exp_p_otr, exp_n_otr;
logic [DWE-1: 0] exp_p_dtr, exp_n_dtr;
logic            exp_9_in,  exp_9_out, exp_9_dir;
logic [  8-1: 0] led_hk;

red_pitaya_hk #(.DWE(DWE+1))

i_hk (
  // system signals
  .clk_i           (adc_clk2d),  // clock
  .rstn_i          (adc_rstn),  // reset - active low
  // LED
  //.led_o           (led_hk),  // LED output
  // idelay control
  .idly_rst_o      (idly_rst    ),
  .idly_ce_o       (idly_ce     ),
  .idly_inc_o      (idly_inc    ),
  .idly_cnt_i      ({idly_cnt[7],idly_cnt[0]}),
  // global configuration
  .digital_loop    (digital_loop),
  .daisy_mode_o    (daisy_mode),
  .pll_sys_i       (adc_10mhz   ),    // system clock
  .pll_ref_i       (pll_ref_i   ),    // reference clock
  .pll_hi_o        (pll_hi_o    ),    // PLL high
  .pll_lo_o        (pll_lo_o    ),    // PLL low
  .diag_i          (locked_pll_cnt_r2),

  // SPI
  .spi_cs_o        (hk_spi_cs   ),
  .spi_clk_o       (hk_spi_clk  ),
  .spi_miso_i      (hk_spi_i    ),
  .spi_mosi_t      (hk_spi_t    ),
  .spi_mosi_o      (hk_spi_o    ),
  // Expansion connector
  .exp_p_dat_i     ({exp_9_in, exp_p_in }),  // input data
  .exp_p_dat_o     ({exp_9_out,exp_p_out}),  // output data
  .exp_p_dir_o     ({exp_9_dir,exp_p_dir}),  // 1-output enable
  .exp_n_dat_i     ({1'b0,     exp_n_in }),
  .exp_n_dat_o     (           exp_n_out ),
  .exp_n_dir_o     (           exp_n_dir ),
   // System bus
  .sys_addr        (sys[0].addr ),
  .sys_wdata       (sys[0].wdata),
  .sys_wen         (sys[0].wen  ),
  .sys_ren         (sys[0].ren  ),
  .sys_rdata       (sys[0].rdata),
  .sys_err         (sys[0].err  ),
  .sys_ack         (sys[0].ack  )
);

////////////////////////////////////////////////////////////////////////////////
// LED
////////////////////////////////////////////////////////////////////////////////

assign led_o = led_hk[7:0];
led i_led (
   // signals
  .clk_i           (adc_clk   ),  // clock
  .rstn_i          (adc_rstn  ),  // reset - active low
  .led_o           (led_o     ),    // LEDs
  //.dat_a_i         (adc_dat[0]),  // in 1
  //.dat_b_i         (adc_dat[1]),  // in 2
  //.dat_a_o         (pid_dat[0]),  // out 1
  //.dat_b_o         (pid_dat[1]),  // out 2
  // System bus
  .sys_addr        (sys[3].addr ),
  .sys_wdata       (sys[3].wdata),
  .sys_wen         (sys[3].wen  ),
  .sys_ren         (sys[3].ren  ),
  .sys_rdata       (sys[3].rdata),
  .sys_err         (sys[3].err  ),
  .sys_ack         (sys[3].ack  )
);

////////////////////////////////////////////////////////////////////////////////
// GPIO
////////////////////////////////////////////////////////////////////////////////

assign trig_output_sel = daisy_mode[2] ? trig_asg_out : scope_trigo;
assign exp_p_otr = exp_p_out;
assign exp_n_otr = exp_n_out | ({DWE{daisy_mode[1]}} & {{DWE-1{1'b0}},trig_output_sel});

assign exp_p_dtr = exp_p_dir;
assign exp_n_dtr = exp_n_dir | ({DWE{daisy_mode[1]}} & {{DWE-1{1'b0}},1'b1});

IOBUF i_iobufp [DWE-1:0] (.O(exp_p_in), .IO(exp_p_io), .I(exp_p_otr), .T(~exp_p_dtr) );
IOBUF i_iobufn [DWE-1:0] (.O(exp_n_in), .IO(exp_n_io), .I(exp_n_otr), .T(~exp_n_dtr) );
IOBUF i_iobuf9           (.O(exp_9_in), .IO(exp_9_io), .I(exp_9_out), .T(~exp_9_dir) );

assign gpio.i[2*GDW-1:  GDW] = exp_p_in[GDW-1:0];
assign gpio.i[3*GDW-1:2*GDW] = exp_n_in[GDW-1:0];

////////////////////////////////////////////////////////////////////////////////
// oscilloscope
////////////////////////////////////////////////////////////////////////////////

logic trig_asg_out;

red_pitaya_scope i_scope (
  // ADC
  .adc_a_i       (adc_dat_sw[0]  ),  // CH 1
  .adc_b_i       (adc_dat_sw[1]  ),  // CH 2
  .adc_clk_i     (adc_clk        ),  // clock
  .adc_clk2d_i   (adc_clk2d      ),  // clock divided
  .adc_rstn_i    (adc_rstn       ),  // reset - active low
  .trig_ext_i    (trig_ext       ),  // external trigger
  .trig_asg_i    (trig_asg_out   ),  // ASG trigger
  .daisy_trig_o  (scope_trigo    ),
  // AXI0 master                 // AXI1 master
  .axi0_clk_o    (axi0_clk   ),  .axi1_clk_o    (axi1_clk   ),
  .axi0_rstn_o   (axi0_rstn  ),  .axi1_rstn_o   (axi1_rstn  ),
  .axi0_waddr_o  (axi0_waddr ),  .axi1_waddr_o  (axi1_waddr ),
  .axi0_wdata_o  (axi0_wdata ),  .axi1_wdata_o  (axi1_wdata ),
  .axi0_wsel_o   (axi0_wsel  ),  .axi1_wsel_o   (axi1_wsel  ),
  .axi0_wvalid_o (axi0_wvalid),  .axi1_wvalid_o (axi1_wvalid),
  .axi0_wlen_o   (axi0_wlen  ),  .axi1_wlen_o   (axi1_wlen  ),
  .axi0_wfixed_o (axi0_wfixed),  .axi1_wfixed_o (axi1_wfixed),
  .axi0_werr_i   (axi0_werr  ),  .axi1_werr_i   (axi1_werr  ),
  .axi0_wrdy_i   (axi0_wrdy  ),  .axi1_wrdy_i   (axi1_wrdy  ),
  // System bus
  .sys_addr      (sys[1].addr ),
  .sys_wdata     (sys[1].wdata),
  .sys_wen       (sys[1].wen  ),
  .sys_ren       (sys[1].ren  ),
  .sys_rdata     (sys[1].rdata),
  .sys_err       (sys[1].err  ),
  .sys_ack       (sys[1].ack  )
);

////////////////////////////////////////////////////////////////////////////////
//  DAC arbitrary signal generator
////////////////////////////////////////////////////////////////////////////////


red_pitaya_asg i_asg (
   // DAC
  .dac_a_o         (asg_dat[0]  ),  // CH 1
  .dac_b_o         (asg_dat[1]  ),  // CH 2
  .dac_clk_i       (adc_clk     ),  // clock
  .dac_rstn_i      (adc_rstn    ),  // reset - active low
  .trig_a_i        (trig_ext    ),
  .trig_b_i        (trig_ext    ),
  .trig_out_o      (trig_asg_out),
  .temp_prot_i     (temp_prot_i ),
  // System bus
  .sys_clk         (adc_clk2d   ),
  .sys_rstn        (adc_rstn    ), 
  .sys_addr        (sys[2].addr ),
  .sys_wdata       (sys[2].wdata),
  .sys_wen         (sys[2].wen  ),
  .sys_ren         (sys[2].ren  ),
  .sys_rdata       (sys[2].rdata),
  .sys_err         (sys[2].err  ),
  .sys_ack         (sys[2].ack  )
);

////////////////////////////////////////////////////////////////////////////////
//  MIMO PID controller
////////////////////////////////////////////////////////////////////////////////

//red_pitaya_pid i_pid (
//   // signals
//  .clk_i           (adc_clk2d ),  // clock
//  .rstn_i          (adc_rstn  ),  // reset - active low
//  .dat_a_i         (adc_dat[0]),  // in 1
//  .dat_b_i         (adc_dat[1]),  // in 2
//  .dat_a_o         (pid_dat[0]),  // out 1
//  .dat_b_o         (pid_dat[1]),  // out 2
//  // System bus
//  .sys_addr        (sys[3].addr ),
//  .sys_wdata       (sys[3].wdata),
//  .sys_wen         (sys[3].wen  ),
//  .sys_ren         (sys[3].ren  ),
//  .sys_rdata       (sys[3].rdata),
//  .sys_err         (sys[3].err  ),
//  .sys_ack         (sys[3].ack  )
//);

//assign sys[3].ack = 1'b1 ;
//assign sys[3].err = 1'b0 ;
//assign sys[3].rdata = 32'h0 ;

assign pid_dat[0] = 14'h0 ;
assign pid_dat[1] = 14'h0 ;



////////////////////////////////////////////////////////////////////////////////
// Daisy test code
////////////////////////////////////////////////////////////////////////////////

wire daisy_rx_rdy ;
wire dly_clk = fclk[3]; // 200MHz clock from PS - used for IDELAY (optionaly)
wire [16-1:0] par_dati = daisy_mode[0] ? {16{trig_output_sel}} : 16'h1234;
wire          par_dvi  = daisy_mode[0] ? 1'b0 : daisy_rx_rdy;

red_pitaya_daisy i_daisy (
   // SATA connector
  .daisy_p_o       (  daisy_p_o                  ),  // line 1 is clock capable
  .daisy_n_o       (  daisy_n_o                  ),
  .daisy_p_i       (  daisy_p_i                  ),  // line 1 is clock capable
  .daisy_n_i       (  daisy_n_i                  ),
   // Data
  .ser_clk_i       (  ser_clk                    ),  // high speed serial
  .dly_clk_i       (  dly_clk                    ),  // delay clock
   // TX
  .par_clk_i       (  adc_clk2d                  ),  // data paralel clock
  .par_rstn_i      (  adc_rstn                   ),  // reset - active low
  .par_rdy_o       (  daisy_rx_rdy               ),
  .par_dv_i        (  par_dvi                    ),
  .par_dat_i       (  par_dati                   ),
   // RX
  .par_clk_o       ( adc_clk_daisy               ),
  .par_rstn_o      (                             ),
  .par_dv_o        (                             ),
  .par_dat_o       ( par_dat                     ),

  .sync_mode_i     (  daisy_mode[0]              ),
  .debug_o         (/*led_o*/                    ),
   // System bus
  .sys_clk_i       (  adc_clk2d                  ),  // clock
  .sys_rstn_i      (  adc_rstn                   ),  // reset - active low
  .sys_addr_i      (  sys[5].addr                ),
  .sys_sel_i       (                             ),
  .sys_wdata_i     (  sys[5].wdata               ),
  .sys_wen_i       (  sys[5].wen                 ),
  .sys_ren_i       (  sys[5].ren                 ),
  .sys_rdata_o     (  sys[5].rdata               ),
  .sys_err_o       (  sys[5].err                 ),
  .sys_ack_o       (  sys[5].ack                 )
);


endmodule: red_pitaya_top
Thanks!

sbenjamin
Posts: 10
Joined: Sun Apr 09, 2023 7:22 am

Re: red_pitaya_top.sv (v0.94_250) modification for GPIO usage

Post by sbenjamin » Mon Dec 25, 2023 1:17 pm

I will add one more question, which is crucial to my understanding and is related to this topic:

Why was I made to think that the correct register to use for "wdata" was 0x40300058, when according to the documentation for the v0.94_250 FPGA memory map https://redpitaya.readthedocs.io/en/lat ... 50_12.html this address is reserved for the PID controller?

Shouldn't I be using a different register/address to pass the LED index?

Thanks!

juretrn
Posts: 110
Joined: Tue Nov 16, 2021 11:38 am

Re: red_pitaya_top.sv (v0.94_250) modification for GPIO usage

Post by juretrn » Thu Dec 28, 2023 10:56 am

Hi,

the current implementation of 250's logic does not implement the PID controller - it has to be enabled by uncommenting the relevant code within _top module.
Therefore, it's perfectly fine to place your "led" module at offset 0x40300000.
With what you currently have, you should be able to access all registers in the range from 0x40300000 to 0x403fffff. Wdata is used to write the data from SW to FPGA. Rdata is used in the opposite direction.

BTW, if you want your LED example to work correctly, you should comment out this line:

Code: Select all

assign led_o = led_hk[7:0]; 
As far as GPIO goes, this is the most relevant part at the top level:

Code: Select all

IOBUF i_iobufp [DWE-1:0] (.O(exp_p_in), .IO(exp_p_io), .I(exp_p_otr), .T(~exp_p_dtr) );
IOBUF i_iobufn [DWE-1:0] (.O(exp_n_in), .IO(exp_n_io), .I(exp_n_otr), .T(~exp_n_dtr) );
where .I ports are inputs toward your logic, .O ports are outputs from your logic, .T are the port direction and .IO is the outward facing port.
Setting T to 1 disables the output buffer - making the IOBUF act as an input. Please note there are in fact 9 GPIO_P and 9 GPIO_N ports (+1 additional exp_9_io).
For more info on IOBUFs, see Xilinx UG471 - 7 Series FPGAs
SelectIO Resources.

Your module will have to interface the IOBUFs directly. You will have to remove existing signals that control them and create your own, in a similar manner to the _hk module which currently controls the GPIOs.

sbenjamin
Posts: 10
Joined: Sun Apr 09, 2023 7:22 am

Re: red_pitaya_top.sv (v0.94_250) modification for GPIO usage

Post by sbenjamin » Thu Dec 28, 2023 11:47 am

Dear juretrn,

Thank you so much for your reply.

The memory I use to pass the LED index from my Console app (using the monitor function via SSH) is 0x40300058 as I mentioned, and as you said it is fine to use this address, but I would like to know which address I SHOULD be using to pass my logic/instructions to my modules? I noticed that 0x40600000 to 0x406FFFFF are defined as FREE for the v0.94_250. Should I be using those addresses instead?

My aim with regards to the GPIO of the SIGNAL lab 250-12 is to use all of them as OUTPUTs. Lets assume for the sake of simplicity, that I'm interested in utilizing only the _p_ GPIOs. Can you please show me which lines I should comment out, and what should be the signature of my GPIO module (lets call it gpio_test.sv), as well as where and how to call it within the red_pitaya_top.sv?
Lets assume that the signature of the gpio_test.sv module should be similar to the led.sv module of mine (replace the led port/output with the GPIO port/buffer).

Thanks and Happy Holidays!

juretrn
Posts: 110
Joined: Tue Nov 16, 2021 11:38 am

Re: red_pitaya_top.sv (v0.94_250) modification for GPIO usage

Post by juretrn » Wed Jan 03, 2024 10:18 am

You can also move your logic to offset 0x40600000 if you wish, it's up to you.
It is probably best to do so, I don't know if any of the existing software tries to access the memory at offset 0x40500000, but I'd say to move your module anyway just for the peace of mind.

At the bare minimum, your code must have a way to determine GPIO port directions and data outputs. At the top level, you must comment out the existing IOBUF declarations and declare your own.

Code: Select all

// signal declarations
wire [DWE-1: 0] my_gpio_p;
wire [DWE-1: 0] my_gpio_p_dir;
wire [DWE-1: 0] my_gpio_n;
wire [DWE-1: 0] my_gpio_n_dir;

// module declaration
gpio_test i_my_gpios (
  // common
  .clk_i           (adc_clk   ),  // clock
  .rstn_i          (adc_rstn  ),  // reset - active low

  // System bus
  .sys_addr        (sys[6].addr ),
  .sys_wdata       (sys[6].wdata),
  .sys_wen         (sys[6].wen  ),
  .sys_ren         (sys[6].ren  ),
  .sys_rdata       (sys[6].rdata),
  .sys_err         (sys[6].err  ),
  .sys_ack         (sys[6].ack  ),

  // Expansion connector
  .exp_p_dat_o     ( my_gpio_p     ),  // output data
  .exp_p_dir_o     ( my_gpio_p_dir ),  // 1-output enable
  .exp_n_dat_o     ( my_gpio_n     ),  // output data
  .exp_n_dir_o     ( my_gpio_n_dir )   // 1-output enable
);

// IO interface
IOBUF i_iobufp [DWE-1:0] (.O(my_gpio_p), .IO(exp_p_io), .I(), .T(~my_gpio_p_dir) );
IOBUF i_iobufn [DWE-1:0] (.O(my_gpio_n), .IO(exp_n_io), .I(), .T(~my_gpio_n_dir) );
Within your module, the direction should at the very least be fixed to output. Better yet, you should add a register that controls the port direction.

Code: Select all

exp_p_dir_o = {9{1'b1}};
exp_n_dir_o = {9{1'b1}};

sbenjamin
Posts: 10
Joined: Sun Apr 09, 2023 7:22 am

Re: red_pitaya_top.sv (v0.94_250) modification for GPIO usage

Post by sbenjamin » Thu Jan 04, 2024 8:23 pm

Thanks juretrn,

So I've commented out all of the code related to the GPIO in the Housekeeping section, as well as all that was in the GPIO section. This is the code I've added to the GPIO section in my top module:

Code: Select all

// signal declarations
wire [DWE-1: 0] my_gpio_p;
wire [DWE-1: 0] my_gpio_p_dir;
wire [DWE-1: 0] my_gpio_n;
wire [DWE-1: 0] my_gpio_n_dir;

// module declaration
gpio_test i_gpio_test (
  // common
  .clk_i           (adc_clk   ),  // clock
  .rstn_i          (adc_rstn  ),  // reset - active low

  // System bus
  .sys_addr        (sys[3].addr ),
  .sys_wdata       (sys[3].wdata),
  .sys_wen         (sys[3].wen  ),
  .sys_ren         (sys[3].ren  ),
  .sys_rdata       (sys[3].rdata),
  .sys_err         (sys[3].err  ),
  .sys_ack         (sys[3].ack  ),

  // Expansion connector
  .exp_p_dat_o     ( my_gpio_p     ),  // output data
  .exp_p_dir_o     ( my_gpio_p_dir ),  // 1-output enable
  .exp_n_dat_o     ( my_gpio_n     ),  // output data
  .exp_n_dir_o     ( my_gpio_n_dir ),   // 1-output enable
  
  // LED
  .led_o           (led_o     )    // LEDs
);

// IO interface
IOBUF i_iobufp [DWE-1:0] (.O(my_gpio_p), .IO(exp_p_io), .I(), .T(~my_gpio_p_dir) );
IOBUF i_iobufn [DWE-1:0] (.O(my_gpio_n), .IO(exp_n_io), .I(), .T(~my_gpio_n_dir) );
And this is my gpio_test.sv module (please ignore my poor HDL):

Code: Select all

module gpio_test (
   // common
  input logic clk_i,               // clock
  input logic rstn_i,              // reset - active low

  // System bus
  input logic [31:0] sys_addr,      // bus address
  input logic [31:0] sys_wdata,     // bus write data
  input logic sys_wen,              // bus write enable
  input logic sys_ren,              // bus read enable
  output logic [31:0] sys_rdata,     // bus read data
  output logic sys_err,             // bus error indicator
  output logic sys_ack,              // bus acknowledge signal

  // Expansion connector
  output logic [8:0] exp_p_dat_o,  // output data
  output logic [8:0] exp_p_dir_o,  // 1-output enable
  output logic [8:0] exp_n_dat_o,  // output data
  output logic [8:0] exp_n_dir_o,   // 1-output enable
  
  // LED
  output logic [7:0] led_o          // led bus 
);

  reg [27:0] counter = 28'd0;
  reg led = 1'b0;
  reg [8:0] p_out = 9'h00;

  assign exp_p_dir_o = {9{1'b1}};// 1-output enable
  assign exp_n_dir_o = {9{1'b1}};// 1-output enable
  
  always_ff @(posedge clk_i or posedge rstn_i) begin
    if (~rstn_i) begin
      counter <= 28'd0;
      led <= 1'b0;
    end else begin
      counter <= counter + 1;
      if (counter == 28'd256000000) begin // 256e6 periods of clock of 128 MHz
        led <= ~led; // led will blink with a period of 2 sec
        counter <= 28'd0; // start again
      end
    end
    
  end

  always_comb begin
//    led_o <= 8'b0; // Initialize LED output
//    exp_p_dat_o <= 9'b0; // Initialize P output
//    exp_n_dat_o <= 9'b0; // Initialize N output
//    if (~led) begin
//      exp_p_dat_o <= 9'h00;
//      exp_n_dat_o <= 9'h00;      
//    end else begin
//      exp_p_dat_o <= 9'hFF;
//      exp_n_dat_o <= 9'hFF;
//    end
    led_o[3] <= led;
    exp_p_dat_o[4] <= led;
    exp_n_dat_o[4] <= led;
  end
endmodule


The LED is blinking as expected, but nothing is coming out of the GPIO pins.

Can you spot anything?

Thanks!

juretrn
Posts: 110
Joined: Tue Nov 16, 2021 11:38 am

Re: red_pitaya_top.sv (v0.94_250) modification for GPIO usage

Post by juretrn » Fri Jan 05, 2024 12:29 am

I do not see anything super obvious in your code except that you should double check your file is .sv (SystemVerilog) because always_comb is not a Verilog construct.

My suggestion is to first simulate your design somehow with the inbuilt Vivado simulator. Unfortunately, the current simulation implementation is a bit clunky, hope you can figure it out.
I have made a huge upgrade to the simulation scripts, but that is coming in the next release :/

sbenjamin
Posts: 10
Joined: Sun Apr 09, 2023 7:22 am

Re: red_pitaya_top.sv (v0.94_250) modification for GPIO usage

Post by sbenjamin » Sun Jan 07, 2024 11:08 am

Thank you for your reply juretrn,

However, I'm not seeing anything in the simulation. I've made the counter/led blink logic to switch every 2 us, so I won't need to wait for long when running the Simulation, but I cannot see anything happening when running the simulation. The LED blinks as expected but the value at the Simulation Waveform is always "0".

I do wish to point out though, that what I'm trying to achieve - modifying the GPIO digital output channels on the FPGA, is a fairly trivial matter. I know that there are numerus projects done on the STEMlab modules, which modify the GPIO pins on the FPGA. How come no one can tell me what to do in order to get started with the FPGA project for the SIGNAL lab module (specifically how to output the Digital Outputs on the FPGA level)?

If someone can send me a simple example, by showing me where to modify the red_pitaya_top.sv module (and why) and what a "gpio_test.sv" module should look like, it would be highly appreciative.

Thank you!

juretrn
Posts: 110
Joined: Tue Nov 16, 2021 11:38 am

Re: red_pitaya_top.sv (v0.94_250) modification for GPIO usage

Post by juretrn » Sun Jan 07, 2024 12:14 pm

My bad, it looks like I didn't check which ports are which on the IOBUF. That's why it's always worth checking the documentation :)

Code: Select all

// IO interface
IOBUF i_iobufp [DWE-1:0] (.O(), .IO(exp_p_io), .I(my_gpio_p), .T(~my_gpio_p_dir) );
IOBUF i_iobufn [DWE-1:0] (.O(), .IO(exp_n_io), .I(my_gpio_n), .T(~my_gpio_n_dir) );
(I'm sure there's a CRITICAL WARNING somewhere in the build report that refers to my_gpio_X being multi driven)

sbenjamin
Posts: 10
Joined: Sun Apr 09, 2023 7:22 am

Re: red_pitaya_top.sv (v0.94_250) modification for GPIO usage

Post by sbenjamin » Sun Jan 07, 2024 5:42 pm

Your bad indeed ;) (just kidding)

Thank you - It works now!

Post Reply
jadalnie klasyczne ekskluzywne meble wypoczynkowe do salonu ekskluzywne meble tapicerowane ekskluzywne meble do sypialni ekskluzywne meble włoskie

Who is online

Users browsing this forum: No registered users and 56 guests