These are the three verilog files I altered - in _top.v it was just to add two external triggers, _block.v was what I attached before and in the main pid.v, I've added the inputs and the memory addresses of the software trigger (I put it at an offset of 0x50).
Code: Select all
/**
* $Id: red_pitaya_top.v 1271 2014-02-25 12:32:34Z matej.oblak $
*
* @brief Red Pitaya TOP module. It connects external pins and PS part with
* other application modules.
*
* @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:
*
* 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
(
// PS connections
`ifdef TOOL_AHEAD
inout [54-1: 0] processing_system7_0_MIO,
input processing_system7_0_PS_SRSTB_pin,
input processing_system7_0_PS_CLK_pin,
input processing_system7_0_PS_PORB_pin,
inout processing_system7_0_DDR_Clk,
inout processing_system7_0_DDR_Clk_n,
inout processing_system7_0_DDR_CKE,
inout processing_system7_0_DDR_CS_n,
inout processing_system7_0_DDR_RAS_n,
inout processing_system7_0_DDR_CAS_n,
output processing_system7_0_DDR_WEB_pin,
inout [ 3-1: 0] processing_system7_0_DDR_BankAddr,
inout [15-1: 0] processing_system7_0_DDR_Addr,
inout processing_system7_0_DDR_ODT,
inout processing_system7_0_DDR_DRSTB,
inout [32-1: 0] processing_system7_0_DDR_DQ,
inout [ 4-1: 0] processing_system7_0_DDR_DM,
inout [ 4-1: 0] processing_system7_0_DDR_DQS,
inout [ 4-1: 0] processing_system7_0_DDR_DQS_n,
inout processing_system7_0_DDR_VRN,
inout processing_system7_0_DDR_VRP,
`endif
`ifdef TOOL_VIVADO
inout [54-1: 0] FIXED_IO_mio ,
inout FIXED_IO_ps_clk ,
inout FIXED_IO_ps_porb ,
inout FIXED_IO_ps_srstb ,
inout FIXED_IO_ddr_vrn ,
inout FIXED_IO_ddr_vrp ,
inout [15-1: 0] DDR_addr ,
inout [ 3-1: 0] DDR_ba ,
inout DDR_cas_n ,
inout DDR_ck_n ,
inout DDR_ck_p ,
inout DDR_cke ,
inout DDR_cs_n ,
inout [ 4-1: 0] DDR_dm ,
inout [32-1: 0] DDR_dq ,
inout [ 4-1: 0] DDR_dqs_n ,
inout [ 4-1: 0] DDR_dqs_p ,
inout DDR_odt ,
inout DDR_ras_n ,
inout DDR_reset_n ,
inout DDR_we_n ,
`endif
// Red Pitaya periphery
// ADC
input [16-1: 2] adc_dat_a_i , // ADC CH1
input [16-1: 2] adc_dat_b_i , // ADC CH2
input adc_clk_p_i , // ADC data clock
input adc_clk_n_i , // ADC data clock
output [ 2-1: 0] adc_clk_o , // optional ADC clock source
output adc_cdcs_o , // ADC clock duty cycle stabilizer
// DAC
output [14-1: 0] dac_dat_o , // DAC combined data
output dac_wrt_o , // DAC write
output dac_sel_o , // DAC channel select
output dac_clk_o , // DAC clock
output dac_rst_o , // DAC reset
// PWM DAC
output [ 4-1: 0] dac_pwm_o , // serial PWM DAC
// XADC
input [ 5-1: 0] vinp_i , // voltages p
input [ 5-1: 0] vinn_i , // voltages n
// Expansion connector
inout [ 8-1: 0] exp_p_io ,
inout [ 8-1: 0] exp_n_io ,
// SATA connector
output [ 2-1: 0] daisy_p_o , // line 1 is clock capable
output [ 2-1: 0] daisy_n_o ,
input [ 2-1: 0] daisy_p_i , // line 1 is clock capable
input [ 2-1: 0] daisy_n_i ,
// LED
output [ 8-1: 0] led_o
);
//---------------------------------------------------------------------------------
//
// Connections to PS
wire [ 4-1: 0] fclk ; //[0]-125MHz, [1]-250MHz, [2]-50MHz, [3]-200MHz
wire [ 4-1: 0] frstn ;
wire ps_sys_clk ;
wire ps_sys_rstn ;
wire [ 32-1: 0] ps_sys_addr ;
wire [ 32-1: 0] ps_sys_wdata ;
wire [ 4-1: 0] ps_sys_sel ;
wire ps_sys_wen ;
wire ps_sys_ren ;
wire [ 32-1: 0] ps_sys_rdata ;
wire ps_sys_err ;
wire ps_sys_ack ;
red_pitaya_ps i_ps
(
`ifdef TOOL_AHEAD
.processing_system7_0_MIO ( processing_system7_0_MIO ),
.processing_system7_0_PS_SRSTB_pin ( processing_system7_0_PS_SRSTB_pin ),
.processing_system7_0_PS_CLK_pin ( processing_system7_0_PS_CLK_pin ),
.processing_system7_0_PS_PORB_pin ( processing_system7_0_PS_PORB_pin ),
.processing_system7_0_DDR_Clk ( processing_system7_0_DDR_Clk ),
.processing_system7_0_DDR_Clk_n ( processing_system7_0_DDR_Clk_n ),
.processing_system7_0_DDR_CKE ( processing_system7_0_DDR_CKE ),
.processing_system7_0_DDR_CS_n ( processing_system7_0_DDR_CS_n ),
.processing_system7_0_DDR_RAS_n ( processing_system7_0_DDR_RAS_n ),
.processing_system7_0_DDR_CAS_n ( processing_system7_0_DDR_CAS_n ),
.processing_system7_0_DDR_WEB_pin ( processing_system7_0_DDR_WEB_pin ),
.processing_system7_0_DDR_BankAddr ( processing_system7_0_DDR_BankAddr ),
.processing_system7_0_DDR_Addr ( processing_system7_0_DDR_Addr ),
.processing_system7_0_DDR_ODT ( processing_system7_0_DDR_ODT ),
.processing_system7_0_DDR_DRSTB ( processing_system7_0_DDR_DRSTB ),
.processing_system7_0_DDR_DQ ( processing_system7_0_DDR_DQ ),
.processing_system7_0_DDR_DM ( processing_system7_0_DDR_DM ),
.processing_system7_0_DDR_DQS ( processing_system7_0_DDR_DQS ),
.processing_system7_0_DDR_DQS_n ( processing_system7_0_DDR_DQS_n ),
.processing_system7_0_DDR_VRN ( processing_system7_0_DDR_VRN ),
.processing_system7_0_DDR_VRP ( processing_system7_0_DDR_VRP ),
`endif
`ifdef TOOL_VIVADO
.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_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 ),
`endif
.fclk_clk_o ( fclk ),
.fclk_rstn_o ( frstn ),
// system read/write channel
.sys_clk_o ( ps_sys_clk ), // system clock
.sys_rstn_o ( ps_sys_rstn ), // system reset - active low
.sys_addr_o ( ps_sys_addr ), // system read/write address
.sys_wdata_o ( ps_sys_wdata ), // system write data
.sys_sel_o ( ps_sys_sel ), // system write byte select
.sys_wen_o ( ps_sys_wen ), // system write enable
.sys_ren_o ( ps_sys_ren ), // system read enable
.sys_rdata_i ( ps_sys_rdata ), // system read data
.sys_err_i ( ps_sys_err ), // system error indicator
.sys_ack_i ( ps_sys_ack ), // system acknowledge signal
// SPI master
.spi_ss_o ( ), // select slave 0
.spi_ss1_o ( ), // select slave 1
.spi_ss2_o ( ), // select slave 2
.spi_sclk_o ( ), // serial clock
.spi_mosi_o ( ), // master out slave in
.spi_miso_i ( 1'b0 ), // master in slave out
// SPI slave
.spi_ss_i ( 1'b1 ), // slave selected
.spi_sclk_i ( 1'b0 ), // serial clock
.spi_mosi_i ( 1'b0 ), // master out slave in
.spi_miso_o ( ) // master in slave out
);
//---------------------------------------------------------------------------------
//
// Analog peripherials
// ADC clock duty cycle stabilizer is enabled
assign adc_cdcs_o = 1'b1 ;
// generating ADC clock is disabled
assign adc_clk_o = 2'b10;
//ODDR i_adc_clk_p ( .Q(adc_clk_o[0]), .D1(1'b1), .D2(1'b0), .C(fclk[0]), .CE(1'b1), .R(1'b0), .S(1'b0));
//ODDR i_adc_clk_n ( .Q(adc_clk_o[1]), .D1(1'b0), .D2(1'b1), .C(fclk[0]), .CE(1'b1), .R(1'b0), .S(1'b0));
wire ser_clk ;
wire adc_clk ;
reg adc_rstn ;
wire [ 14-1: 0] adc_a ;
wire [ 14-1: 0] adc_b ;
reg [ 14-1: 0] dac_a ;
reg [ 14-1: 0] dac_b ;
wire [ 24-1: 0] dac_pwm_a ;
wire [ 24-1: 0] dac_pwm_b ;
wire [ 24-1: 0] dac_pwm_c ;
wire [ 24-1: 0] dac_pwm_d ;
red_pitaya_analog i_analog
(
// ADC IC
.adc_dat_a_i ( adc_dat_a_i ), // CH 1
.adc_dat_b_i ( adc_dat_b_i ), // CH 2
.adc_clk_p_i ( adc_clk_p_i ), // data clock
.adc_clk_n_i ( adc_clk_n_i ), // data clock
// DAC IC
.dac_dat_o ( dac_dat_o ), // combined data
.dac_wrt_o ( dac_wrt_o ), // write enable
.dac_sel_o ( dac_sel_o ), // channel select
.dac_clk_o ( dac_clk_o ), // clock
.dac_rst_o ( dac_rst_o ), // reset
// PWM DAC
.dac_pwm_o ( dac_pwm_o ), // serial PWM DAC
// user interface
.adc_dat_a_o ( adc_a ), // ADC CH1
.adc_dat_b_o ( adc_b ), // ADC CH2
.adc_clk_o ( adc_clk ), // ADC received clock
.adc_rst_i ( adc_rstn ), // reset - active low
.ser_clk_o ( ser_clk ), // fast serial clock
.dac_dat_a_i ( dac_a ), // DAC CH1
.dac_dat_b_i ( dac_b ), // DAC CH2
.dac_pwm_a_i ( dac_pwm_a ), // slow DAC CH1
.dac_pwm_b_i ( dac_pwm_b ), // slow DAC CH2
.dac_pwm_c_i ( dac_pwm_c ), // slow DAC CH3
.dac_pwm_d_i ( dac_pwm_d ), // slow DAC CH4
.dac_pwm_sync_o ( ) // slow DAC sync
);
always @(posedge adc_clk) begin
adc_rstn <= frstn[0] ;
end
//---------------------------------------------------------------------------------
//
// system bus decoder & multiplexer
// it breaks memory addresses into 8 regions
wire sys_clk = ps_sys_clk ;
wire sys_rstn = ps_sys_rstn ;
wire [ 32-1: 0] sys_addr = ps_sys_addr ;
wire [ 32-1: 0] sys_wdata = ps_sys_wdata ;
wire [ 4-1: 0] sys_sel = ps_sys_sel ;
wire [ 8-1: 0] sys_wen ;
wire [ 8-1: 0] sys_ren ;
wire [(8*32)-1: 0] sys_rdata ;
wire [ (8*1)-1: 0] sys_err ;
wire [ (8*1)-1: 0] sys_ack ;
reg [ 8-1: 0] sys_cs ;
always @(sys_addr) begin
sys_cs = 8'h0 ;
case (sys_addr[22:20])
3'h0, 3'h1, 3'h2, 3'h3, 3'h4, 3'h5, 3'h6, 3'h7 :
sys_cs[sys_addr[22:20]] = 1'b1 ;
endcase
end
assign sys_wen = sys_cs & {8{ps_sys_wen}} ;
assign sys_ren = sys_cs & {8{ps_sys_ren}} ;
assign ps_sys_rdata = {32{sys_cs[ 0]}} & sys_rdata[ 0*32+31: 0*32] |
{32{sys_cs[ 1]}} & sys_rdata[ 1*32+31: 1*32] |
{32{sys_cs[ 2]}} & sys_rdata[ 2*32+31: 2*32] |
{32{sys_cs[ 3]}} & sys_rdata[ 3*32+31: 3*32] |
{32{sys_cs[ 4]}} & sys_rdata[ 4*32+31: 4*32] |
{32{sys_cs[ 5]}} & sys_rdata[ 5*32+31: 5*32] |
{32{sys_cs[ 6]}} & sys_rdata[ 6*32+31: 6*32] |
{32{sys_cs[ 7]}} & sys_rdata[ 7*32+31: 7*32] ;
assign ps_sys_err = sys_cs[ 0] & sys_err[ 0] |
sys_cs[ 1] & sys_err[ 1] |
sys_cs[ 2] & sys_err[ 2] |
sys_cs[ 3] & sys_err[ 3] |
sys_cs[ 4] & sys_err[ 4] |
sys_cs[ 5] & sys_err[ 5] |
sys_cs[ 6] & sys_err[ 6] |
sys_cs[ 7] & sys_err[ 7] ;
assign ps_sys_ack = sys_cs[ 0] & sys_ack[ 0] |
sys_cs[ 1] & sys_ack[ 1] |
sys_cs[ 2] & sys_ack[ 2] |
sys_cs[ 3] & sys_ack[ 3] |
sys_cs[ 4] & sys_ack[ 4] |
sys_cs[ 5] & sys_ack[ 5] |
sys_cs[ 6] & sys_ack[ 6] |
sys_cs[ 7] & sys_ack[ 7] ;
assign sys_rdata[ 6*32+31: 6*32] = 32'h0;
assign sys_err[6] = {1{1'b0}} ;
assign sys_ack[6] = {1{1'b1}} ;
//---------------------------------------------------------------------------------
//
// House Keeping
wire [ 8-1: 0] exp_p_in ;
wire [ 8-1: 0] exp_p_out ;
wire [ 8-1: 0] exp_p_dir ;
wire [ 8-1: 0] exp_n_in ;
wire [ 8-1: 0] exp_n_out ;
wire [ 8-1: 0] exp_n_dir ;
red_pitaya_hk i_hk
(
.clk_i ( adc_clk ), // clock
.rstn_i ( adc_rstn ), // reset - active low
// LED
.led_o ( led_o ), // LED output
// Expansion connector
.exp_p_dat_i ( exp_p_in ), // input data
.exp_p_dat_o ( exp_p_out ), // output data
.exp_p_dir_o ( exp_p_dir ), // 1-output enable
.exp_n_dat_i ( exp_n_in ),
.exp_n_dat_o ( exp_n_out ),
.exp_n_dir_o ( exp_n_dir ),
// System bus
.sys_clk_i ( sys_clk ), // clock
.sys_rstn_i ( sys_rstn ), // reset - active low
.sys_addr_i ( sys_addr ), // address
.sys_wdata_i ( sys_wdata ), // write data
.sys_sel_i ( sys_sel ), // write byte select
.sys_wen_i ( sys_wen[0] ), // write enable
.sys_ren_i ( sys_ren[0] ), // read enable
.sys_rdata_o ( sys_rdata[ 0*32+31: 0*32] ), // read data
.sys_err_o ( sys_err[0] ), // error indicator
.sys_ack_o ( sys_ack[0] ) // acknowledge signal
);
genvar GV ;
generate
for( GV = 0 ; GV < 8 ; GV = GV + 1)
begin : exp_iobuf
IOBUF i_iobufp (.O(exp_p_in[GV]), .IO(exp_p_io[GV]), .I(exp_p_out[GV]), .T(!exp_p_dir[GV]) );
IOBUF i_iobufn (.O(exp_n_in[GV]), .IO(exp_n_io[GV]), .I(exp_n_out[GV]), .T(!exp_n_dir[GV]) );
end
endgenerate
//---------------------------------------------------------------------------------
//
// Oscilloscope application
wire trig_asg_out ;
red_pitaya_scope i_scope
(
// ADC
.adc_a_i ( adc_a ), // CH 1
.adc_b_i ( adc_b ), // CH 2
.adc_clk_i ( adc_clk ), // clock
.adc_rstn_i ( adc_rstn ), // reset - active low
.trig_ext_i ( exp_p_in[0] ), // external trigger
.trig_asg_i ( trig_asg_out ), // ASG trigger
// System bus
.sys_clk_i ( sys_clk ), // clock
.sys_rstn_i ( sys_rstn ), // reset - active low
.sys_addr_i ( sys_addr ), // address
.sys_wdata_i ( sys_wdata ), // write data
.sys_sel_i ( sys_sel ), // write byte select
.sys_wen_i ( sys_wen[1] ), // write enable
.sys_ren_i ( sys_ren[1] ), // read enable
.sys_rdata_o ( sys_rdata[ 1*32+31: 1*32] ), // read data
.sys_err_o ( sys_err[1] ), // error indicator
.sys_ack_o ( sys_ack[1] ) // acknowledge signal
);
//---------------------------------------------------------------------------------
//
// DAC arbitrary signal generator
wire [ 14-1: 0] asg_a ;
wire [ 14-1: 0] asg_b ;
red_pitaya_asg i_asg
(
// DAC
.dac_a_o ( asg_a ), // CH 1
.dac_b_o ( asg_b ), // CH 2
.dac_clk_i ( adc_clk ), // clock
.dac_rstn_i ( adc_rstn ), // reset - active low
.trig_a_i ( exp_p_in[0] ),
.trig_b_i ( exp_p_in[0] ),
.trig_out_o ( trig_asg_out ),
// System bus
.sys_clk_i ( sys_clk ), // clock
.sys_rstn_i ( sys_rstn ), // reset - active low
.sys_addr_i ( sys_addr ), // address
.sys_wdata_i ( sys_wdata ), // write data
.sys_sel_i ( sys_sel ), // write byte select
.sys_wen_i ( sys_wen[2] ), // write enable
.sys_ren_i ( sys_ren[2] ), // read enable
.sys_rdata_o ( sys_rdata[ 2*32+31: 2*32] ), // read data
.sys_err_o ( sys_err[2] ), // error indicator
.sys_ack_o ( sys_ack[2] ) // acknowledge signal
);
//---------------------------------------------------------------------------------
//
// MIMO PID controller
wire [ 14-1: 0] pid_a ;
wire [ 14-1: 0] pid_b ;
red_pitaya_pid i_pid
(
// signals
.clk_i ( adc_clk ), // clock
.rstn_i ( adc_rstn ), // reset - active low
.dat_a_i ( adc_a ), // in 1
.dat_b_i ( adc_b ), // in 2
.dat_a_o ( pid_a ), // out 1
.dat_b_o ( pid_b ), // out 2
.hold_input1 ( exp_p_in[0] ), //hold input 1
.hold_input2 ( exp_p_in[1] ), //hold input 2
// System bus
.sys_clk_i ( sys_clk ), // clock
.sys_rstn_i ( sys_rstn ), // reset - active low
.sys_addr_i ( sys_addr ), // address
.sys_wdata_i ( sys_wdata ), // write data
.sys_sel_i ( sys_sel ), // write byte select
.sys_wen_i ( sys_wen[3] ), // write enable
.sys_ren_i ( sys_ren[3] ), // read enable
.sys_rdata_o ( sys_rdata[ 3*32+31: 3*32] ), // read data
.sys_err_o ( sys_err[3] ), // error indicator
.sys_ack_o ( sys_ack[3] ) // acknowledge signal
);
//---------------------------------------------------------------------------------
//
// Sumation of ASG and PID signal
// perform saturation before sending to DAC
wire [ 15-1: 0] dac_a_sum ;
wire [ 15-1: 0] dac_b_sum ;
assign dac_a_sum = $signed(asg_a) + $signed(pid_a);
assign dac_b_sum = $signed(asg_b) + $signed(pid_b);
always @(*) begin
if (dac_a_sum[15-1:15-2] == 2'b01) // pos. overflow
dac_a <= 14'h1FFF ;
else if (dac_a_sum[15-1:15-2] == 2'b10) // neg. overflow
dac_a <= 14'h2000 ;
else
dac_a <= dac_a_sum[14-1:0] ;
if (dac_b_sum[15-1:15-2] == 2'b01) // pos. overflow
dac_b <= 14'h1FFF ;
else if (dac_b_sum[15-1:15-2] == 2'b10) // neg. overflow
dac_b <= 14'h2000 ;
else
dac_b <= dac_b_sum[14-1:0] ;
end
//---------------------------------------------------------------------------------
//
// Analog mixed signals
// XADC and slow PWM DAC control
red_pitaya_ams i_ams
(
// power test
.clk_i ( adc_clk ), // clock
.rstn_i ( adc_rstn ), // reset - active low
.vinp_i ( vinp_i ), // voltages p
.vinn_i ( vinn_i ), // voltages n
.dac_a_o ( dac_pwm_a ), // values used for
.dac_b_o ( dac_pwm_b ), // conversion into PWM signal
.dac_c_o ( dac_pwm_c ),
.dac_d_o ( dac_pwm_d ),
// System bus
.sys_clk_i ( sys_clk ), // clock
.sys_rstn_i ( sys_rstn ), // reset - active low
.sys_addr_i ( sys_addr ), // address
.sys_wdata_i ( sys_wdata ), // write data
.sys_sel_i ( sys_sel ), // write byte select
.sys_wen_i ( sys_wen[4] ), // write enable
.sys_ren_i ( sys_ren[4] ), // read enable
.sys_rdata_o ( sys_rdata[ 4*32+31: 4*32] ), // read data
.sys_err_o ( sys_err[4] ), // error indicator
.sys_ack_o ( sys_ack[4] ) // acknowledge signal
);
//---------------------------------------------------------------------------------
//
// Daisy chain
// simple communication module
wire daisy_rx_rdy ;
wire dly_clk = fclk[3]; // 200MHz clock from PS - used for IDELAY (optionaly)
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_clk ), // data paralel clock
.par_rstn_i ( adc_rstn ), // reset - active low
.par_rdy_o ( daisy_rx_rdy ),
.par_dv_i ( daisy_rx_rdy ),
.par_dat_i ( 16'h1234 ),
// RX
.par_clk_o ( ),
.par_rstn_o ( ),
.par_dv_o ( ),
.par_dat_o ( ),
.debug_o (/*led_o*/ ),
// System bus
.sys_clk_i ( sys_clk ), // clock
.sys_rstn_i ( sys_rstn ), // reset - active low
.sys_addr_i ( sys_addr ), // address
.sys_wdata_i ( sys_wdata ), // write data
.sys_sel_i ( sys_sel ), // write byte select
.sys_wen_i ( sys_wen[5] ), // write enable
.sys_ren_i ( sys_ren[5] ), // read enable
.sys_rdata_o ( sys_rdata[ 5*32+31: 5*32] ), // read data
.sys_err_o ( sys_err[5] ), // error indicator
.sys_ack_o ( sys_ack[5] ) // acknowledge signal
);
//---------------------------------------------------------------------------------
//
// Power consumtion test
red_pitaya_test i_test
(
// power test
.clk_i ( adc_clk ), // clock
.rstn_i ( adc_rstn ), // reset - active low
.rand_o ( ),
// System bus
.sys_clk_i ( sys_clk ), // clock
.sys_rstn_i ( sys_rstn ), // reset - active low
.sys_addr_i ( sys_addr ), // address
.sys_wdata_i ( sys_wdata ), // write data
.sys_sel_i ( sys_sel ), // write byte select
.sys_wen_i ( sys_wen[7] ), // write enable
.sys_ren_i ( sys_ren[7] ), // read enable
.sys_rdata_o ( sys_rdata[ 7*32+31: 7*32] ), // read data
.sys_err_o ( sys_err[7] ), // error indicator
.sys_ack_o ( sys_ack[7] ) // acknowledge signal
);
//assign sys_rdata[ 7*32+31: 7*32] = 32'h0 ;
//assign sys_err[7] = 1'b0 ;
//assign sys_ack[7] = 1'b1 ;
endmodule
Code: Select all
/**
* $Id: red_pitaya_pid.v 961 2014-01-21 11:40:39Z matej.oblak $
*
* @brief Red Pitaya MIMO PID controller.
*
* @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:
*
* Multiple input multiple output controller.
*
*
* /-------\ /-----------\
* CHA -----+--> | PID11 | ------| SUM & SAT | ---> CHA
* | \-------/ \-----------/
* | ^
* | /-------\ |
* ---> | PID21 | ---------- |
* \-------/ | |
* | |
* INPUT | | OUTPUT
* | |
* /-------\ | |
* ---> | PID12 | --------------
* | \-------/ |
* | Àá
* | /-------\ /-----------\
* CHB -----+--> | PID22 | ------| SUM & SAT | ---> CHB
* \-------/ \-----------/
*
*
* MIMO controller is build from four equal submodules, each can have
* different settings.
*
* Each output is sum of two controllers with different input. That sum is also
* saturated to protect from wrapping.
*
*/
module red_pitaya_pid
(
// signals
input clk_i , //!< processing clock
input rstn_i , //!< processing reset - active low
input [ 14-1: 0] dat_a_i , //!< input data CHA
input [ 14-1: 0] dat_b_i , //!< input data CHB
output [ 14-1: 0] dat_a_o , //!< output data CHA
output [ 14-1: 0] dat_b_o , //!< output data CHB
input hold_input1 , //hold input 1
input hold_input2 , //hold input 2
// 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 [ 32-1: 0] sys_rdata_o , //!< bus read data
output sys_err_o , //!< bus error indicator
output sys_ack_o //!< bus acknowledge signal
);
wire [ 32-1: 0] addr ;
wire [ 32-1: 0] wdata ;
wire wen ;
wire ren ;
reg [ 32-1: 0] rdata ;
reg err ;
reg ack ;
localparam PSR = 12 ;
localparam ISR = 18 ;
localparam DSR = 10 ;
//---------------------------------------------------------------------------------
// PID 11
wire [ 14-1: 0] pid_11_out ;
reg [ 14-1: 0] set_11_sp ;
reg [ 14-1: 0] set_11_kp ;
reg [ 14-1: 0] set_11_ki ;
reg [ 14-1: 0] set_11_kd ;
reg set_11_irst ;
reg set_11_ihold ;
red_pitaya_pid_block #(
.PSR ( PSR ),
.ISR ( ISR ),
.DSR ( DSR )
)
i_pid11
(
// data
.clk_i ( clk_i ), // clock
.rstn_i ( rstn_i ), // reset - active low
.dat_i ( dat_a_i ), // input data
.dat_o ( pid_11_out ), // output data
.pid_hold_pin ( hold_input1 ), //external
// settings
.set_sp_i ( set_11_sp ), // set point
.set_kp_i ( set_11_kp ), // Kp
.set_ki_i ( set_11_ki ), // Ki
.set_kd_i ( set_11_kd ), // Kd
.int_rst_i ( set_11_irst ), // integrator reset
.int_hold_i ( set_11_ihold ) //internal
);
//---------------------------------------------------------------------------------
// PID 21
wire [ 14-1: 0] pid_21_out ;
reg [ 14-1: 0] set_21_sp ;
reg [ 14-1: 0] set_21_kp ;
reg [ 14-1: 0] set_21_ki ;
reg [ 14-1: 0] set_21_kd ;
reg set_21_irst ;
reg set_21_ihold ;
red_pitaya_pid_block #(
.PSR ( PSR ),
.ISR ( ISR ),
.DSR ( DSR )
)
i_pid21
(
// data
.clk_i ( clk_i ), // clock
.rstn_i ( rstn_i ), // reset - active low
.dat_i ( dat_a_i ), // input data
.dat_o ( pid_21_out ), // output data
.pid_hold_pin ( hold_input1 ), //external
// settings
.set_sp_i ( set_21_sp ), // set point
.set_kp_i ( set_21_kp ), // Kp
.set_ki_i ( set_21_ki ), // Ki
.set_kd_i ( set_21_kd ), // Kd
.int_rst_i ( set_21_irst ), // integrator reset
.int_hold_i ( set_21_ihold ) //internal
);
//---------------------------------------------------------------------------------
// PID 12
wire [ 14-1: 0] pid_12_out ;
reg [ 14-1: 0] set_12_sp ;
reg [ 14-1: 0] set_12_kp ;
reg [ 14-1: 0] set_12_ki ;
reg [ 14-1: 0] set_12_kd ;
reg set_12_irst ;
reg set_12_ihold ;
red_pitaya_pid_block #(
.PSR ( PSR ),
.ISR ( ISR ),
.DSR ( DSR )
)
i_pid12
(
// data
.clk_i ( clk_i ), // clock
.rstn_i ( rstn_i ), // reset - active low
.dat_i ( dat_b_i ), // input data
.dat_o ( pid_12_out ), // output data
.pid_hold_pin ( hold_input2 ), //external
// settings
.set_sp_i ( set_12_sp ), // set point
.set_kp_i ( set_12_kp ), // Kp
.set_ki_i ( set_12_ki ), // Ki
.set_kd_i ( set_12_kd ), // Kd
.int_rst_i ( set_12_irst ), // integrator reset
.int_hold_i ( set_12_ihold ) //internal
);
//---------------------------------------------------------------------------------
// PID 22
wire [ 14-1: 0] pid_22_out ;
reg [ 14-1: 0] set_22_sp ;
reg [ 14-1: 0] set_22_kp ;
reg [ 14-1: 0] set_22_ki ;
reg [ 14-1: 0] set_22_kd ;
reg set_22_irst ;
reg set_22_ihold ;
red_pitaya_pid_block #(
.PSR ( PSR ),
.ISR ( ISR ),
.DSR ( DSR )
)
i_pid22
(
// data
.clk_i ( clk_i ), // clock
.rstn_i ( rstn_i ), // reset - active low
.dat_i ( dat_b_i ), // input data
.dat_o ( pid_22_out ), // output data
.pid_hold_pin ( hold_input2 ), //external
// settings
.set_sp_i ( set_22_sp ), // set point
.set_kp_i ( set_22_kp ), // Kp
.set_ki_i ( set_22_ki ), // Ki
.set_kd_i ( set_22_kd ), // Kd
.int_rst_i ( set_22_irst ), // integrator reset
.int_hold_i ( set_22_ihold ) //internal
);
//---------------------------------------------------------------------------------
// Sum and saturation
wire [ 15-1: 0] out_1_sum ;
reg [ 14-1: 0] out_1_sat ;
wire [ 15-1: 0] out_2_sum ;
reg [ 14-1: 0] out_2_sat ;
assign out_1_sum = $signed(pid_11_out) + $signed(pid_12_out);
assign out_2_sum = $signed(pid_22_out) + $signed(pid_21_out);
always @(posedge clk_i) begin
if (rstn_i == 1'b0) begin
out_1_sat <= 14'd0 ;
out_2_sat <= 14'd0 ;
end
else begin
if (out_1_sum[15-1:15-2]==2'b01) // postitive sat
out_1_sat <= 14'h1FFF ;
else if (out_1_sum[15-1:15-2]==2'b10) // negative sat
out_1_sat <= 14'h2000 ;
else
out_1_sat <= out_1_sum[14-1:0] ;
if (out_2_sum[15-1:15-2]==2'b01) // postitive sat
out_2_sat <= 14'h1FFF ;
else if (out_2_sum[15-1:15-2]==2'b10) // negative sat
out_2_sat <= 14'h2000 ;
else
out_2_sat <= out_2_sum[14-1:0] ;
end
end
assign dat_a_o = out_1_sat ;
assign dat_b_o = out_2_sat ;
//---------------------------------------------------------------------------------
//
// System bus connection
always @(posedge clk_i) begin
if (rstn_i == 1'b0) begin
set_11_sp <= 14'd0 ;
set_11_kp <= 14'd0 ;
set_11_ki <= 14'd0 ;
set_11_kd <= 14'd0 ;
set_11_irst <= 1'b1 ;
set_11_ihold <= 1'b0 ;
set_12_sp <= 14'd0 ;
set_12_kp <= 14'd0 ;
set_12_ki <= 14'd0 ;
set_12_kd <= 14'd0 ;
set_12_irst <= 1'b1 ;
set_12_ihold <= 1'b0 ;
set_21_sp <= 14'd0 ;
set_21_kp <= 14'd0 ;
set_21_ki <= 14'd0 ;
set_21_kd <= 14'd0 ;
set_21_irst <= 1'b1 ;
set_21_ihold <= 1'b0 ;
set_22_sp <= 14'd0 ;
set_22_kp <= 14'd0 ;
set_22_ki <= 14'd0 ;
set_22_kd <= 14'd0 ;
set_22_irst <= 1'b1 ;
set_22_ihold <= 1'b0 ;
end
else begin
if (wen) begin
if (addr[19:0]==16'h0) {set_22_irst,set_21_irst,set_12_irst,set_11_irst} <= wdata[ 4-1:0] ;
if (addr[19:0]==16'h10) set_11_sp <= wdata[14-1:0] ;
if (addr[19:0]==16'h14) set_11_kp <= wdata[14-1:0] ;
if (addr[19:0]==16'h18) set_11_ki <= wdata[14-1:0] ;
if (addr[19:0]==16'h1C) set_11_kd <= wdata[14-1:0] ;
if (addr[19:0]==16'h20) set_12_sp <= wdata[14-1:0] ;
if (addr[19:0]==16'h24) set_12_kp <= wdata[14-1:0] ;
if (addr[19:0]==16'h28) set_12_ki <= wdata[14-1:0] ;
if (addr[19:0]==16'h2C) set_12_kd <= wdata[14-1:0] ;
if (addr[19:0]==16'h30) set_21_sp <= wdata[14-1:0] ;
if (addr[19:0]==16'h34) set_21_kp <= wdata[14-1:0] ;
if (addr[19:0]==16'h38) set_21_ki <= wdata[14-1:0] ;
if (addr[19:0]==16'h3C) set_21_kd <= wdata[14-1:0] ;
if (addr[19:0]==16'h40) set_22_sp <= wdata[14-1:0] ;
if (addr[19:0]==16'h44) set_22_kp <= wdata[14-1:0] ;
if (addr[19:0]==16'h48) set_22_ki <= wdata[14-1:0] ;
if (addr[19:0]==16'h4C) set_22_kd <= wdata[14-1:0] ;
if (addr[19:0]==16'h50) {set_22_ihold,set_21_ihold,set_12_ihold,set_11_ihold} <= wdata[ 4-1:0] ;
end
end
end
always @(*) begin
err <= 1'b0 ;
casez (addr[19:0])
20'h00 : begin ack <= 1'b1; rdata <= {{32- 4{1'b0}}, set_22_irst,set_21_irst,set_12_irst,set_11_irst} ; end
20'h10 : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_11_sp} ; end
20'h14 : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_11_kp} ; end
20'h18 : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_11_ki} ; end
20'h1C : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_11_kd} ; end
20'h20 : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_12_sp} ; end
20'h24 : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_12_kp} ; end
20'h28 : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_12_ki} ; end
20'h2C : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_12_kd} ; end
20'h30 : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_21_sp} ; end
20'h34 : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_21_kp} ; end
20'h38 : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_21_ki} ; end
20'h3C : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_21_kd} ; end
20'h40 : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_22_sp} ; end
20'h44 : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_22_kp} ; end
20'h48 : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_22_ki} ; end
20'h4C : begin ack <= 1'b1; rdata <= {{32-14{1'b0}}, set_22_kd} ; end
20'h50 : begin ack <= 1'b1; rdata <= {{32- 4{1'b0}}, set_22_ihold,set_21_ihold,set_12_ihold,set_11_ihold} ; end
default : begin ack <= 1'b1; rdata <= 32'h0 ; end
endcase
end
// bridge between processing and sys clock
bus_clk_bridge i_bridge
(
.sys_clk_i ( sys_clk_i ),
.sys_rstn_i ( sys_rstn_i ),
.sys_addr_i ( sys_addr_i ),
.sys_wdata_i ( sys_wdata_i ),
.sys_sel_i ( sys_sel_i ),
.sys_wen_i ( sys_wen_i ),
.sys_ren_i ( sys_ren_i ),
.sys_rdata_o ( sys_rdata_o ),
.sys_err_o ( sys_err_o ),
.sys_ack_o ( sys_ack_o ),
.clk_i ( clk_i ),
.rstn_i ( rstn_i ),
.addr_o ( addr ),
.wdata_o ( wdata ),
.wen_o ( wen ),
.ren_o ( ren ),
.rdata_i ( rdata ),
.err_i ( err ),
.ack_i ( ack )
);
endmodule