cariboulabs-cariboulite/firmware/io_ctrl.v

310 wiersze
12 KiB
Verilog

module io_ctrl
(
input i_rst_b,
input i_sys_clk, // FPGA Clock
input [4:0] i_ioc,
input [7:0] i_data_in,
output reg [7:0] o_data_out,
input i_cs,
input i_fetch_cmd,
input i_load_cmd,
// Digital interfaces
input i_button,
input [3:0] i_config,
output o_led0,
output o_led1,
output [3:0] o_pmod,
// Analog interfaces
output o_mixer_fm,
output o_rx_h_tx_l,
output o_rx_h_tx_l_b,
output o_tr_vc1,
output o_tr_vc1_b,
output o_tr_vc2,
output o_shdn_tx_lna,
output o_shdn_rx_lna,
output o_mixer_en
);
//=========================================================================
// CONSTANT DEFINITIONS
//=========================================================================
// MODULE SPECIFIC IOC LIST
localparam
ioc_module_version = 5'b00000, // read only
ioc_mode = 5'b00001, // The functional mode-of-operation of the system.
ioc_dig_pin = 5'b00010, // Digital pin control and read
ioc_pmod_dir = 5'b00011, // PMOD connector bits IO pin direction
ioc_pmod_val = 5'b00100, // PMOD connector bits IO pin value
ioc_rf_pin = 5'b00101; // Setting up / reading out the pin values controlling the RF front-end path switches.
// MODULE SPECIFIC PARAMS
localparam
module_version = 8'b00000001;
// Debug state definitions
localparam
debug_mode_none = 2'b00, // No-debug mode - the RFM field describes a set of pre-determines modes of operation
debug_mode_debug = 2'b01; // Debug mode - the RFM field directives are ignored and the RF-I/O settings are explicitly set in pin-level
// RF-mode states
localparam // RF Mode of operation - this setting is active only when DBG='00'
rf_mode_low_power = 3'b000, // Low-power / inactive mode - all RF peripherals are turned off (LNAs, Mixer, etc.)
rf_mode_bypass = 3'b001, // RF front-end wide-range tuning is turned off, and the modem 2.4GHz
rf_mode_rx_lpf = 3'b010, // RX Lowpass mode - tuned to receive high-frequency signals (>2.483 GHz)
rf_mode_rx_hpf = 3'b011, // RX Highpass mode - tuned to receive low-frequency signals (<2.4 GHz)
rf_mode_tx_lpf = 3'b100, // TX Lowpass mode - tuned to transmit low-frequency signals (<2.4 GHz)
rf_mode_tx_hpf = 3'b101; // TX Highpass mode - tuned to transmit high-frequency signals (>2.4 GHz)
//=========================================================================
// INTERNAL REGISTERS
//=========================================================================
// Internal registers
reg [1:0] debug_mode;
reg [2:0] rf_mode;
// Digital outputs
reg led0_state;
reg led1_state;
reg [7:0] pmod_dir_state;
reg [3:0] pmod_state;
reg [7:0] rf_pin_state;
reg mixer_en_state;
// Analog parts outputs
reg lna_rx_shutdown_state;
reg lna_tx_shutdown_state;
reg rx_h_state;
reg rx_h_b_state;
reg tr_vc_1_state;
reg tr_vc_1_b_state;
reg tr_vc_2_state;
//=========================================================================
// LOGICAL SIGNAL ASSIGNMENTS
//=========================================================================
assign o_led0 = led0_state;
assign o_led1 = led1_state;
assign o_pmod = pmod_state;
// Analog interfaces
assign o_mixer_fm = 1'b0;
assign o_rx_h_tx_l = rx_h_state;
assign o_rx_h_tx_l_b = rx_h_b_state;
assign o_tr_vc1 = tr_vc_1_state;
assign o_tr_vc1_b = tr_vc_1_b_state;
assign o_tr_vc2 = tr_vc_2_state;
assign o_shdn_tx_lna = lna_tx_shutdown_state;
assign o_shdn_rx_lna = lna_rx_shutdown_state;
//assign o_mixer_en = mixer_en_state;
assign o_mixer_en = 1'b1;
//=========================================================================
// BUS COMMUNICATION LOGIC & RF CONTROL
//=========================================================================
always @(posedge i_sys_clk or negedge i_rst_b)
begin
if (i_rst_b == 1'b0) begin
debug_mode <= debug_mode_none;
rf_mode <= rf_mode_low_power;
led0_state <= 1'b0;
led1_state <= 1'b0;
end else begin
if (i_cs == 1'b1) begin
//=============================================
// READ OPERATIONS
//=============================================
if (i_fetch_cmd == 1'b1) begin
case (i_ioc)
//----------------------------------------------
ioc_module_version: o_data_out <= module_version;
//----------------------------------------------
ioc_mode: begin
o_data_out[1:0] <= debug_mode;
o_data_out[4:2] <= rf_mode;
end
//----------------------------------------------
ioc_dig_pin: begin
o_data_out[0] <= led0_state;
o_data_out[1] <= led1_state;
o_data_out[6:3] <= i_config;
o_data_out[7] <= i_button;
end
//----------------------------------------------
ioc_pmod_dir: begin
o_data_out <= pmod_dir_state;
end
//----------------------------------------------
ioc_pmod_val: begin
o_data_out[3:0] <= pmod_state;
o_data_out[7:4] <= 4'b0000;
end
//----------------------------------------------
ioc_rf_pin: begin
o_data_out[0] <= mixer_en_state;
o_data_out[1] <= lna_rx_shutdown_state;
o_data_out[2] <= lna_tx_shutdown_state;
o_data_out[3] <= tr_vc_2_state;
o_data_out[4] <= tr_vc_1_b_state;
o_data_out[5] <= tr_vc_1_state;
o_data_out[6] <= rx_h_b_state;
o_data_out[7] <= rx_h_state;
end
endcase
end
//=============================================
// WRITE OPERATIONS
//=============================================
else if (i_load_cmd == 1'b1) begin
case (i_ioc)
//----------------------------------------------
ioc_mode: begin
debug_mode <= i_data_in[1:0];
rf_mode <= i_data_in[4:2];
if (i_data_in[1:0] == debug_mode_none) begin
// TBD move back all the controls to good position
// use rf_mode to control everything
end
end
//----------------------------------------------
ioc_dig_pin: begin
led0_state <= i_data_in[0];
led1_state <= i_data_in[1];
end
//----------------------------------------------
ioc_pmod_dir: begin
pmod_dir_state <= i_data_in;
end
//----------------------------------------------
ioc_pmod_val: begin
pmod_state[3:0] <= i_data_in[3:0];
end
//----------------------------------------------
ioc_rf_pin: begin
rf_pin_state <= i_data_in;
end
//----------------------------------------------
endcase
end
end
end
end
always @(posedge i_sys_clk or negedge i_rst_b)
begin
if (i_rst_b == 1'b0) begin
end
// this is relevant only if the system runs
// in an operational mode
else if (debug_mode == debug_mode_none) begin
case (rf_mode)
//--------------------------------------------------
rf_mode_low_power: begin
mixer_en_state <= 1'b0;
lna_rx_shutdown_state <= 1'b1;
lna_tx_shutdown_state <= 1'b1;
tr_vc_1_state <= 1'b0;
tr_vc_1_b_state <= 1'b1;
tr_vc_2_state <= 1'b0;
rx_h_state <= 1'b0;
rx_h_b_state <= 1'b1;
end
//--------------------------------------------------
rf_mode_bypass: begin
mixer_en_state <= 1'b0;
lna_rx_shutdown_state <= 1'b1;
lna_tx_shutdown_state <= 1'b1;
tr_vc_1_state <= 1'b1;
tr_vc_1_b_state <= 1'b0;
tr_vc_2_state <= 1'b0;
rx_h_state <= 1'b0;
rx_h_b_state <= 1'b1;
end
//--------------------------------------------------
rf_mode_rx_lpf: begin
mixer_en_state <= 1'b1;
lna_rx_shutdown_state <= 1'b0;
lna_tx_shutdown_state <= 1'b1;
tr_vc_1_state <= 1'b0;
tr_vc_1_b_state <= 1'b1;
tr_vc_2_state <= 1'b1;
rx_h_state <= 1'b1;
rx_h_b_state <= 1'b0;
end
//--------------------------------------------------
rf_mode_rx_hpf: begin
mixer_en_state <= 1'b1;
lna_rx_shutdown_state <= 1'b0;
lna_tx_shutdown_state <= 1'b1;
tr_vc_1_state <= 1'b0;
tr_vc_1_b_state <= 1'b1;
tr_vc_2_state <= 1'b1;
rx_h_state <= 1'b0;
rx_h_b_state <= 1'b1;
end
//--------------------------------------------------
rf_mode_tx_lpf: begin
mixer_en_state <= 1'b1;
lna_rx_shutdown_state <= 1'b1;
lna_tx_shutdown_state <= 1'b0;
tr_vc_1_state <= 1'b1;
tr_vc_1_b_state <= 1'b0;
tr_vc_2_state <= 1'b1;
rx_h_state <= 1'b0;
rx_h_b_state <= 1'b1;
end
//--------------------------------------------------
rf_mode_tx_hpf: begin
mixer_en_state <= 1'b1;
lna_rx_shutdown_state <= 1'b1;
lna_tx_shutdown_state <= 1'b0;
tr_vc_1_state <= 1'b1;
tr_vc_1_b_state <= 1'b0;
tr_vc_2_state <= 1'b1;
rx_h_state <= 1'b1;
rx_h_b_state <= 1'b0;
end
//--------------------------------------------------
endcase
end else if (debug_mode == debug_mode_debug) begin
mixer_en_state <= rf_pin_state[0];
lna_rx_shutdown_state <= rf_pin_state[1];
lna_tx_shutdown_state <= rf_pin_state[2];
tr_vc_2_state <= rf_pin_state[3];
tr_vc_1_b_state <= rf_pin_state[4];
tr_vc_1_state <= rf_pin_state[5];
rx_h_b_state <= rf_pin_state[6];
rx_h_state <= rf_pin_state[7];
end
end
endmodule // io_ctrl