Help - DIO pin FPGA control from editted FPGA blink tutorial

Applications, development tools, FPGA, C, WEB
Post Reply
oliverburrow
Posts: 8
Joined: Wed Feb 17, 2016 7:27 pm

Help - DIO pin FPGA control from editted FPGA blink tutorial

Post by oliverburrow » Wed Jun 29, 2016 10:46 am

Hi,

I am new to FPGA, verilog and vivado. I saw the following, FPGA blink tutorial, and figured this was a good place to start. I succesfully editted the code to make LED's flash in funky patterns.

http://redpitaya.com/examples-new/fpga- ... -tutorial/

What I tried to do next was to edit the example to make the digital pins turn on an off. What I've achieved is the pin voltages changing slighty, by 50 mV. I was expecting 3.3V. I don't think this is measurement issue, as if I turn the pins on using the API (in C) the voltages go to the expected 3.3V. My output also has about 50 mV, 50 Hz noise on it, but this doesn't surprise me.

I suspect the problem is with my code, what I tried to do was emulate the LED control for the DIO p pins. Specifically I was trying to get pin 7 to pulse at 0.47 Hz. I think my edits are
  • - exp_p_dat_o and exp_p_dir_o are no longer registers. Lines 42-43.
    - Inserted the example for the LED control. Lines 78-90.
    - Added two reg [7:0] pin_reg, pin_on. These were intended to emulate led_reg in the LED example for the pin output and setting the pin to output. Line 79
    - Replacing instances of exp_p_dat_o and exp_p_dir_o with pin_reg and pin_on in the always block triggered by the clock rising edge. Lines 164,165,172 and 174


Can anyone help me correct this? It's trying to do what I want, I'm hopeful I've just missed something simple. Thanks in advance.

My code is as follows

Code: Select all

/**
 * $Id: red_pitaya_hk.v 961 2014-01-21 11:40:39Z matej.oblak $
 *
 * @brief Red Pitaya house keeping.
 *
 * @Author Matej Oblak
 *
 * (c) Red Pitaya  http://www.redpitaya.com
 *
 * This part of code is written in Verilog hardware description language (HDL).
 * Please visit http://en.wikipedia.org/wiki/Verilog
 * for more details on the language used herein.
 */



/**
 * GENERAL DESCRIPTION:
 *
 * House keeping module takes care of system identification.
 *
 *
 * This module takes care of system identification via DNA readout at startup and
 * ID register which user can define at compile time.
 *
 * Beside that it is currently also used to test expansion connector and for
 * driving LEDs.
 * 
 */





module red_pitaya_hk
(
   // LED
   output     [  8-1: 0] led_o           ,  //!< LED output

   // Expansion connector
   input      [  8-1: 0] exp_p_dat_i     ,  //!< exp. con. input data
   output [8-1: 0] exp_p_dat_o     ,  //!< exp. con. output data
   output  [8-1: 0] exp_p_dir_o     ,  //!< exp. con. 1-output enable
   input      [  8-1: 0] exp_n_dat_i     ,  //!<
   output reg [  8-1: 0] exp_n_dat_o     ,  //!<
   output reg [  8-1: 0] exp_n_dir_o     ,  //!<

   // XADC  
   input      [ 12-1: 0] adc_v_i         ,  //!< measured temperatures and voltage supplies
   input      [ 12-1: 0] adc_temp_i      ,
   input      [ 12-1: 0] adc_pint_i      ,
   input      [ 12-1: 0] adc_paux_i      ,
   input      [ 12-1: 0] adc_bram_i      ,
   input      [ 12-1: 0] adc_int_i       ,
   input      [ 12-1: 0] adc_aux_i       ,
   input      [ 12-1: 0] adc_ddr_i       ,

   // System bus
   input                 sys_clk_i       ,  //!< bus clock
   input                 sys_rstn_i      ,  //!< bus reset - active low
   input      [ 32-1: 0] sys_addr_i      ,  //!< bus address
   input      [ 32-1: 0] sys_wdata_i     ,  //!< bus write data
   input      [  4-1: 0] sys_sel_i       ,  //!< bus write byte select
   input                 sys_wen_i       ,  //!< bus write enable
   input                 sys_ren_i       ,  //!< bus read enable
   output reg [ 32-1: 0] sys_rdata_o     ,  //!< bus read data
   output reg            sys_err_o       ,  //!< bus error indicator
   output reg            sys_ack_o          //!< bus acknowledge signal

);





//---------------------------------------------------------------------------------
//
//  Simple LED logic
reg [8-1:0] led_reg, pin_reg, pin_on;
reg [27:0] led_counter;
always @(posedge sys_clk_i) begin
if (!sys_rstn_i) begin led_counter <= 28'h0; 
end 
else begin led_counter <= led_counter + 28'h1; 
end
end

assign exp_p_dir_o  = {1'd1,pin_on[6:0]};
assign exp_p_dat_o  = {led_counter[16],pin_reg[6:0]};
//assign led_o = {led_counter[27],led_reg[6:0]};


//---------------------------------------------------------------------------------
//
//  Read device DNA

wire           dna_dout  ;
reg            dna_clk   ;
reg            dna_read  ;
reg            dna_shift ;
reg  [ 9-1: 0] dna_cnt   ;
reg  [57-1: 0] dna_value ;
reg            dna_done  ;

always @(posedge sys_clk_i) begin
   if (sys_rstn_i == 1'b0) begin
      dna_clk   <=  1'b0 ;
      dna_read  <=  1'b0 ;
      dna_shift <=  1'b0 ;
      dna_cnt   <=  9'd0 ;
      dna_value <= 57'd0 ;
      dna_done  <=  1'b0 ;
   end
   else begin
      if (!dna_done)
         dna_cnt <= dna_cnt + 1'd1 ;

      dna_clk <= dna_cnt[2] ;
      dna_read  <= (dna_cnt < 9'd10);
      dna_shift <= (dna_cnt > 9'd18);

      if ((dna_cnt[2:0]==3'h0) && !dna_done)
         dna_value <= {dna_value[57-2:0], dna_dout};

      if (dna_cnt > 9'd465)
         dna_done <= 1'b1;

   end
end

DNA_PORT #( .SIM_DNA_VALUE(57'h0823456789ABCDE) ) // Specifies a sample 57-bit DNA value for simulation
i_DNA 
(
  .DOUT  ( dna_dout   ), // 1-bit output: DNA output data.
  .CLK   ( dna_clk    ), // 1-bit input: Clock input.
  .DIN   ( 1'b0       ), // 1-bit input: User data input pin.
  .READ  ( dna_read   ), // 1-bit input: Active high load DNA, active low read input.
  .SHIFT ( dna_shift  )  // 1-bit input: Active high shift enable input.
);





//---------------------------------------------------------------------------------
//
//  Desing identification

wire [32-1: 0] id_value ;

assign id_value[31: 4] = 28'h0 ; // reserved
assign id_value[ 3: 0] =  4'h1 ; // board type   1-release1





//---------------------------------------------------------------------------------
//
//  System bus connection

always @(posedge sys_clk_i) begin
   if (sys_rstn_i == 1'b0) begin
      led_reg[7:0] <= 8'h0 ;
      pin_reg[7:0]  <= 8'h0 ;
      pin_on[7:0]  <= 8'h0 ;
      exp_n_dat_o  <= 8'h0 ;
      exp_n_dir_o  <= 8'h0 ;
   end
   else begin
      if (sys_wen_i) begin
         if (sys_addr_i[19:0]==20'h10)   pin_on[7:0]  <= sys_wdata_i[8-1:0] ;
         if (sys_addr_i[19:0]==20'h14)   exp_n_dir_o  <= sys_wdata_i[8-1:0] ;
         if (sys_addr_i[19:0]==20'h18)   pin_reg[7:0]  <= sys_wdata_i[8-1:0] ;
         if (sys_addr_i[19:0]==20'h1C)   exp_n_dat_o  <= sys_wdata_i[8-1:0] ;

         if (sys_addr_i[19:0]==20'h30)   led_reg[7:0] <= sys_wdata_i[8-1:0] ;
      end
   end
end





always @(*) begin
   sys_err_o <= 1'b0 ;

   casez (sys_addr_i[19:0])
     20'h00000 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {               id_value  }                          ; end
     20'h00004 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {               dna_value[31: 0] }                   ; end
     20'h00008 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32-25{1'b0}}, dna_value[56:32] }                   ; end

     20'h00010 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32- 8{1'b0}}, exp_p_dir_o }                        ; end
     20'h00014 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32- 8{1'b0}}, exp_n_dir_o }                        ; end
     20'h00018 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32- 8{1'b0}}, exp_p_dat_o }                        ; end
     20'h0001C : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32- 8{1'b0}}, exp_n_dat_o }                        ; end
     20'h00020 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32- 8{1'b0}}, exp_p_dat_i }                        ; end
     20'h00024 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32- 8{1'b0}}, exp_n_dat_i }                        ; end

     20'h00200 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32-12{1'b0}}, adc_v_i }                            ; end
     20'h00204 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32-12{1'b0}}, adc_temp_i }                         ; end
     20'h00208 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32-12{1'b0}}, adc_pint_i }                         ; end
     20'h0020c : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32-12{1'b0}}, adc_paux_i }                         ; end
     20'h00210 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32-12{1'b0}}, adc_bram_i }                         ; end
     20'h00214 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32-12{1'b0}}, adc_int_i }                          ; end
     20'h00218 : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32-12{1'b0}}, adc_aux_i }                          ; end
     20'h0021c : begin sys_ack_o <= 1'b1;          sys_rdata_o <= {{32-12{1'b0}}, adc_ddr_i }                          ; end

       default : begin sys_ack_o <= 1'b1;          sys_rdata_o <=  32'h0                                               ; end
   endcase
end





endmodule


Nils Roos
Posts: 1441
Joined: Sat Jun 07, 2014 12:49 pm
Location: Königswinter

Re: Help - DIO pin FPGA control from editted FPGA blink tuto

Post by Nils Roos » Wed Jun 29, 2016 12:04 pm

You moved the tap on the counter from led_counter[27] to led_counter[16], so your output is actually oscillating at about 1kHz.

As a matter of good practice, you should define reset behaviour for registers, the state of pin_reg and pin_on is undefined in your code.

oliverburrow
Posts: 8
Joined: Wed Feb 17, 2016 7:27 pm

Re: Help - DIO pin FPGA control from editted FPGA blink tuto

Post by oliverburrow » Wed Jun 29, 2016 3:26 pm

Hi Nils, thanks for the reply.

I had forgotten I had changed the tap counter in this code, but I am aware of the consequences on the rate of oscillation. I was checking if the issue was specific to the 0.5 Hz, which it is not.

I understand the concept of defining reset behaviour of the pins. I have attempted to do this by adding in similar assignment in the case of low sys_rstn_i.

Code: Select all

//  Simple LED logic
reg [8-1:0] led_reg, pin_reg, pin_on;
reg [27:0] led_counter;
always @(posedge sys_clk_i) begin
if (!sys_rstn_i) begin led_counter <= 28'h0;
pin_on <= 8'h0;
pin_reg <= 8'h0;
end 
else begin led_counter <= led_counter + 28'h1; 
end
end

assign exp_p_dir_o  = {1'd1,pin_on[6:0]};
assign exp_p_dat_o  = {led_counter[27],pin_reg[6:0]};
However I am still observing the same problem. Any help is appreciated. I have been working on the assumption that controlling the DIO pins is similar to controlling the LEDs, as they are in the API. Is this a poor assumption?

Nils Roos
Posts: 1441
Joined: Sat Jun 07, 2014 12:49 pm
Location: Königswinter

Re: Help - DIO pin FPGA control from editted FPGA blink tuto

Post by Nils Roos » Wed Jun 29, 2016 5:50 pm

I just saw that you had already introduced the proper reset instructions in the first version of your code in lines 164,165 by replacing exp_* with your new registers.

When I load the modified example to a Red Pitaya, I see the expected oscillation with 3.3V amplitude. I also measure a slight crosstalk on the neighboring pins, so maybe you were looking for your signal on the wrong pin?

oliverburrow
Posts: 8
Joined: Wed Feb 17, 2016 7:27 pm

Re: Help - DIO pin FPGA control from editted FPGA blink tuto

Post by oliverburrow » Thu Jun 30, 2016 10:28 am

Yes! That was rather silly of me. I was measuring the n pin. I was convinced it was a programming error.

Thank you for your help!

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 98 guests