kopia lustrzana https://github.com/cariboulabs/cariboulite
Tx side integration firmware
rodzic
132d19259c
commit
0595990c8d
|
@ -2,23 +2,23 @@ module complex_fifo #(
|
||||||
parameter ADDR_WIDTH = 10,
|
parameter ADDR_WIDTH = 10,
|
||||||
parameter DATA_WIDTH = 16
|
parameter DATA_WIDTH = 16
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input wire wr_rst_b_i,
|
input wire wr_rst_b_i,
|
||||||
input wire wr_clk_i,
|
input wire wr_clk_i,
|
||||||
input wire wr_en_i,
|
input wire wr_en_i,
|
||||||
input wire [2*DATA_WIDTH-1:0] wr_data_i,
|
input wire [2*DATA_WIDTH-1:0] wr_data_i,
|
||||||
|
|
||||||
input wire rd_rst_b_i,
|
input wire rd_rst_b_i,
|
||||||
input wire rd_clk_i,
|
input wire rd_clk_i,
|
||||||
input wire rd_en_i,
|
input wire rd_en_i,
|
||||||
output reg [2*DATA_WIDTH-1:0] rd_data_o,
|
output reg [2*DATA_WIDTH-1:0] rd_data_o,
|
||||||
|
|
||||||
output reg full_o,
|
output reg full_o,
|
||||||
output reg empty_o,
|
output reg empty_o,
|
||||||
|
|
||||||
input wire debug_pull,
|
input wire debug_pull,
|
||||||
input wire debug_push,
|
input wire debug_push,
|
||||||
);
|
);
|
||||||
|
|
||||||
reg [ADDR_WIDTH-1:0] wr_addr;
|
reg [ADDR_WIDTH-1:0] wr_addr;
|
||||||
reg [ADDR_WIDTH-1:0] wr_addr_gray;
|
reg [ADDR_WIDTH-1:0] wr_addr_gray;
|
||||||
|
@ -32,11 +32,10 @@ module complex_fifo #(
|
||||||
reg [2*DATA_WIDTH-1:0] debug_buffer;
|
reg [2*DATA_WIDTH-1:0] debug_buffer;
|
||||||
|
|
||||||
function [ADDR_WIDTH-1:0] gray_conv;
|
function [ADDR_WIDTH-1:0] gray_conv;
|
||||||
input [ADDR_WIDTH-1:0] in;
|
input [ADDR_WIDTH-1:0] in;
|
||||||
begin
|
begin
|
||||||
gray_conv = {in[ADDR_WIDTH-1],
|
gray_conv = {in[ADDR_WIDTH-1], in[ADDR_WIDTH-2:0] ^ in[ADDR_WIDTH-1:1]};
|
||||||
in[ADDR_WIDTH-2:0] ^ in[ADDR_WIDTH-1:1]};
|
end
|
||||||
end
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
always @(posedge wr_clk_i) begin
|
always @(posedge wr_clk_i) begin
|
||||||
|
@ -55,13 +54,15 @@ module complex_fifo #(
|
||||||
rd_addr_gray_wr_r <= rd_addr_gray_wr;
|
rd_addr_gray_wr_r <= rd_addr_gray_wr;
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge wr_clk_i)
|
always @(posedge wr_clk_i) begin
|
||||||
if (wr_rst_b_i == 1'b0)
|
if (wr_rst_b_i == 1'b0) begin
|
||||||
full_o <= 0;
|
full_o <= 0;
|
||||||
else if (wr_en_i)
|
end else if (wr_en_i) begin
|
||||||
full_o <= gray_conv(wr_addr + 2) == rd_addr_gray_wr_r;
|
full_o <= gray_conv(wr_addr + 2) == rd_addr_gray_wr_r;
|
||||||
else
|
end else begin
|
||||||
full_o <= full_o & (gray_conv(wr_addr + 1'b1) == rd_addr_gray_wr_r);
|
full_o <= full_o & (gray_conv(wr_addr + 1'b1) == rd_addr_gray_wr_r);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
always @(posedge rd_clk_i) begin
|
always @(posedge rd_clk_i) begin
|
||||||
if (rd_rst_b_i == 1'b0) begin
|
if (rd_rst_b_i == 1'b0) begin
|
||||||
|
@ -80,15 +81,15 @@ module complex_fifo #(
|
||||||
wr_addr_gray_rd_r <= wr_addr_gray_rd;
|
wr_addr_gray_rd_r <= wr_addr_gray_rd;
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge rd_clk_i)
|
always @(posedge rd_clk_i) begin
|
||||||
if (rd_rst_b_i == 1'b0)
|
if (rd_rst_b_i == 1'b0) begin
|
||||||
empty_o <= 1'b1;
|
empty_o <= 1'b1;
|
||||||
else if (rd_en_i)
|
end else if (rd_en_i) begin
|
||||||
empty_o <= gray_conv(rd_addr + 1) == wr_addr_gray_rd_r;
|
empty_o <= gray_conv(rd_addr + 1) == wr_addr_gray_rd_r;
|
||||||
else
|
end else begin
|
||||||
empty_o <= empty_o & (gray_conv(rd_addr) == wr_addr_gray_rd_r);
|
empty_o <= empty_o & (gray_conv(rd_addr) == wr_addr_gray_rd_r);
|
||||||
|
end
|
||||||
//reg [DATA_WIDTH-1:0] mem[(1<<ADDR_WIDTH)-1:0];
|
end
|
||||||
|
|
||||||
always @(posedge rd_clk_i) begin
|
always @(posedge rd_clk_i) begin
|
||||||
if (rd_en_i) begin
|
if (rd_en_i) begin
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2012, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Based on vga_fifo_dc.v in Richard Herveille's VGA/LCD core
|
|
||||||
* Copyright (C) 2001 Richard Herveille <richard@asics.ws>
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and non-source forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in non-source form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS WORK IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* WORK, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
module dual_clock_fifo #(
|
|
||||||
parameter ADDR_WIDTH = 8,
|
|
||||||
parameter DATA_WIDTH = 16
|
|
||||||
)
|
|
||||||
(
|
|
||||||
input wire wr_rst_i,
|
|
||||||
input wire wr_clk_i,
|
|
||||||
input wire wr_en_i,
|
|
||||||
input wire [DATA_WIDTH-1:0] wr_data_i,
|
|
||||||
|
|
||||||
input wire rd_rst_i,
|
|
||||||
input wire rd_clk_i,
|
|
||||||
input wire rd_en_i,
|
|
||||||
output reg [DATA_WIDTH-1:0] rd_data_o,
|
|
||||||
|
|
||||||
output reg full_o,
|
|
||||||
output reg empty_o
|
|
||||||
);
|
|
||||||
|
|
||||||
reg [ADDR_WIDTH-1:0] wr_addr;
|
|
||||||
reg [ADDR_WIDTH-1:0] wr_addr_gray;
|
|
||||||
reg [ADDR_WIDTH-1:0] wr_addr_gray_rd;
|
|
||||||
reg [ADDR_WIDTH-1:0] wr_addr_gray_rd_r;
|
|
||||||
reg [ADDR_WIDTH-1:0] rd_addr;
|
|
||||||
reg [ADDR_WIDTH-1:0] rd_addr_gray;
|
|
||||||
reg [ADDR_WIDTH-1:0] rd_addr_gray_wr;
|
|
||||||
reg [ADDR_WIDTH-1:0] rd_addr_gray_wr_r;
|
|
||||||
|
|
||||||
function [ADDR_WIDTH-1:0] gray_conv;
|
|
||||||
input [ADDR_WIDTH-1:0] in;
|
|
||||||
begin
|
|
||||||
gray_conv = {in[ADDR_WIDTH-1],
|
|
||||||
in[ADDR_WIDTH-2:0] ^ in[ADDR_WIDTH-1:1]};
|
|
||||||
end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
always @(posedge wr_clk_i) begin
|
|
||||||
if (wr_rst_i) begin
|
|
||||||
wr_addr <= 0;
|
|
||||||
wr_addr_gray <= 0;
|
|
||||||
end else if (wr_en_i) begin
|
|
||||||
wr_addr <= wr_addr + 1'b1;
|
|
||||||
wr_addr_gray <= gray_conv(wr_addr + 1'b1);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// synchronize read address to write clock domain
|
|
||||||
always @(posedge wr_clk_i) begin
|
|
||||||
rd_addr_gray_wr <= rd_addr_gray;
|
|
||||||
rd_addr_gray_wr_r <= rd_addr_gray_wr;
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(posedge wr_clk_i)
|
|
||||||
if (wr_rst_i)
|
|
||||||
full_o <= 0;
|
|
||||||
else if (wr_en_i)
|
|
||||||
full_o <= gray_conv(wr_addr + 2) == rd_addr_gray_wr_r;
|
|
||||||
else
|
|
||||||
full_o <= full_o & (gray_conv(wr_addr + 1'b1) == rd_addr_gray_wr_r);
|
|
||||||
|
|
||||||
always @(posedge rd_clk_i) begin
|
|
||||||
if (rd_rst_i) begin
|
|
||||||
rd_addr <= 0;
|
|
||||||
rd_addr_gray <= 0;
|
|
||||||
end else if (rd_en_i) begin
|
|
||||||
rd_addr <= rd_addr + 1'b1;
|
|
||||||
rd_addr_gray <= gray_conv(rd_addr + 1'b1);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// synchronize write address to read clock domain
|
|
||||||
always @(posedge rd_clk_i) begin
|
|
||||||
wr_addr_gray_rd <= wr_addr_gray;
|
|
||||||
wr_addr_gray_rd_r <= wr_addr_gray_rd;
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(posedge rd_clk_i)
|
|
||||||
if (rd_rst_i)
|
|
||||||
empty_o <= 1'b1;
|
|
||||||
else if (rd_en_i)
|
|
||||||
empty_o <= gray_conv(rd_addr + 1) == wr_addr_gray_rd_r;
|
|
||||||
else
|
|
||||||
empty_o <= empty_o & (gray_conv(rd_addr) == wr_addr_gray_rd_r);
|
|
||||||
|
|
||||||
reg [DATA_WIDTH-1:0] mem[(1<<ADDR_WIDTH)-1:0];
|
|
||||||
|
|
||||||
always @(posedge rd_clk_i)
|
|
||||||
if (rd_en_i)
|
|
||||||
rd_data_o <= mem[rd_addr];
|
|
||||||
|
|
||||||
always @(posedge wr_clk_i)
|
|
||||||
if (wr_en_i)
|
|
||||||
mem[wr_addr] <= wr_data_i;
|
|
||||||
endmodule
|
|
|
@ -25,49 +25,49 @@
|
||||||
# For the iCE40 (iCE40LP1K-QN84)
|
# For the iCE40 (iCE40LP1K-QN84)
|
||||||
|
|
||||||
|
|
||||||
#set_frequency i_glob_clock 125
|
#set_frequency i_glob_clock 125
|
||||||
#set_frequency w_clock_sys 64
|
#set_frequency w_clock_sys 64
|
||||||
#set_frequency smi_ctrl_ins.soe_and_reset 16
|
#set_frequency smi_ctrl_ins.soe_and_reset 16
|
||||||
#set_frequency i_smi_swe_srw 16
|
#set_frequency i_smi_swe_srw 16
|
||||||
set_frequency lvds_clock_buf 64
|
set_frequency lvds_clock_buf 64
|
||||||
#set_frequency i_sck 5
|
#set_frequency i_sck 5
|
||||||
|
|
||||||
# CLOCK
|
# CLOCK
|
||||||
set_io i_glob_clock A29
|
set_io i_glob_clock A29
|
||||||
set_io i_rst_b A43
|
set_io i_rst_b A43
|
||||||
|
|
||||||
# PMOD
|
# PMOD
|
||||||
set_io io_pmod[0] B24
|
set_io io_pmod[0] B24
|
||||||
set_io io_pmod[1] A31
|
set_io io_pmod[1] A31
|
||||||
set_io io_pmod[2] B23
|
set_io io_pmod[2] B23
|
||||||
set_io io_pmod[3] B21
|
set_io io_pmod[3] B21
|
||||||
set_io io_pmod[4] A25
|
set_io io_pmod[4] A25
|
||||||
set_io io_pmod[5] A26
|
set_io io_pmod[5] A26
|
||||||
set_io io_pmod[6] A27
|
set_io io_pmod[6] A27
|
||||||
set_io io_pmod[7] B20
|
set_io io_pmod[7] B20
|
||||||
|
|
||||||
# MIXER
|
# MIXER
|
||||||
set_io o_mixer_fm A32
|
set_io o_mixer_fm A32
|
||||||
set_io o_mixer_en B22
|
set_io o_mixer_en B22
|
||||||
|
|
||||||
# RF FRONT-END PATH
|
# RF FRONT-END PATH
|
||||||
set_io o_rx_h_tx_l A33
|
set_io o_rx_h_tx_l A33
|
||||||
set_io o_rx_h_tx_l_b A35
|
set_io o_rx_h_tx_l_b A35
|
||||||
set_io o_tr_vc1 A34
|
set_io o_tr_vc1 A34
|
||||||
set_io o_tr_vc1_b B27
|
set_io o_tr_vc1_b B27
|
||||||
set_io o_tr_vc2 B26
|
set_io o_tr_vc2 B26
|
||||||
set_io o_shdn_rx_lna A46
|
set_io o_shdn_rx_lna A46
|
||||||
set_io o_shdn_tx_lna B36
|
set_io o_shdn_tx_lna B36
|
||||||
|
|
||||||
# LVDS TO MODEM
|
# LVDS TO MODEM
|
||||||
set_io o_iq_tx_p B4
|
set_io o_iq_tx_p B4
|
||||||
set_io o_iq_tx_n A5
|
set_io o_iq_tx_n A5
|
||||||
set_io o_iq_tx_clk_p A10
|
set_io o_iq_tx_clk_p A10
|
||||||
set_io o_iq_tx_clk_n B8
|
set_io o_iq_tx_clk_n B8
|
||||||
|
|
||||||
set_io i_iq_rx_09_p A4 # Paired with i_iq_rx_09_n @ B3 - positive logic
|
set_io i_iq_rx_09_p A4 # Paired with i_iq_rx_09_n @ B3 - positive logic
|
||||||
set_io i_iq_rx_24_n A2 # Paired with i_iq_rx_24_p @ B1 - negative logic - needs to be negated
|
set_io i_iq_rx_24_n A2 # Paired with i_iq_rx_24_p @ B1 - negative logic - needs to be negated
|
||||||
set_io i_iq_rx_clk_p A3 # Paired with i_iq_rx_clk_n @ B2 - positive logic
|
set_io i_iq_rx_clk_p A3 # Paired with i_iq_rx_clk_n @ B2 - positive logic
|
||||||
|
|
||||||
# DIGITAL I/F
|
# DIGITAL I/F
|
||||||
set_io -pullup yes i_config[0] B29
|
set_io -pullup yes i_config[0] B29
|
||||||
|
@ -79,25 +79,25 @@ set_io o_led0 A38
|
||||||
set_io o_led1 A39
|
set_io o_led1 A39
|
||||||
|
|
||||||
# SMI TO RPI
|
# SMI TO RPI
|
||||||
set_io o_smi_write_req A19
|
set_io o_smi_write_req A19
|
||||||
set_io o_smi_read_req B19
|
set_io o_smi_read_req B19
|
||||||
set_io i_smi_a2 A48
|
set_io i_smi_a2 A48
|
||||||
set_io i_smi_a3 A47
|
set_io i_smi_a3 A47
|
||||||
|
|
||||||
set_io i_smi_soe_se B15
|
set_io i_smi_soe_se B15
|
||||||
set_io i_smi_swe_srw B13
|
set_io i_smi_swe_srw B13
|
||||||
set_io io_smi_data[0] A16
|
set_io io_smi_data[0] A16
|
||||||
set_io io_smi_data[1] B11
|
set_io io_smi_data[1] B11
|
||||||
set_io io_smi_data[2] B10
|
set_io io_smi_data[2] B10
|
||||||
set_io io_smi_data[3] B12
|
set_io io_smi_data[3] B12
|
||||||
set_io io_smi_data[4] B14
|
set_io io_smi_data[4] B14
|
||||||
set_io io_smi_data[5] A20
|
set_io io_smi_data[5] A20
|
||||||
set_io io_smi_data[6] A13
|
set_io io_smi_data[6] A13
|
||||||
set_io io_smi_data[7] A14
|
set_io io_smi_data[7] A14
|
||||||
|
|
||||||
# SPI
|
# SPI
|
||||||
set_io i_mosi A22
|
set_io i_mosi A22
|
||||||
set_io i_sck A23
|
set_io i_sck A23
|
||||||
set_io i_ss B18
|
set_io i_ss B18
|
||||||
set_io o_miso B17
|
set_io o_miso B17
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
module io_ctrl
|
module io_ctrl
|
||||||
(
|
(
|
||||||
input i_rst_b,
|
input i_rst_b,
|
||||||
input i_sys_clk, // FPGA Clock
|
input i_sys_clk, // FPGA Clock
|
||||||
|
|
||||||
input [4:0] i_ioc,
|
input [4:0] i_ioc,
|
||||||
|
|
|
@ -1,95 +1,87 @@
|
||||||
module lvds_rx
|
module lvds_rx (
|
||||||
(
|
input i_rst_b,
|
||||||
input i_rst_b,
|
input i_ddr_clk,
|
||||||
input i_ddr_clk,
|
input [1:0] i_ddr_data,
|
||||||
input [1:0] i_ddr_data,
|
|
||||||
|
|
||||||
input i_fifo_full,
|
input i_fifo_full,
|
||||||
output o_fifo_write_clk,
|
output o_fifo_write_clk,
|
||||||
output o_fifo_push,
|
output o_fifo_push,
|
||||||
output reg [31:0] o_fifo_data,
|
output reg [31:0] o_fifo_data,
|
||||||
input i_sync_input,
|
input i_sync_input,
|
||||||
output [1:0] o_debug_state );
|
output [ 1:0] o_debug_state
|
||||||
|
);
|
||||||
|
|
||||||
// Internal FSM States
|
// Internal FSM States
|
||||||
localparam
|
localparam state_idle = 2'b00, state_i_phase = 2'b01, state_q_phase = 2'b11;
|
||||||
state_idle = 3'b00,
|
|
||||||
state_i_phase = 3'b01,
|
|
||||||
state_q_phase = 3'b11;
|
|
||||||
|
|
||||||
// Modem sync symbols
|
// Modem sync symbols
|
||||||
localparam
|
localparam modem_i_sync = 2'b10, modem_q_sync = 2'b01;
|
||||||
modem_i_sync = 3'b10,
|
|
||||||
modem_q_sync = 3'b01;
|
|
||||||
|
|
||||||
// Internal Registers
|
// Internal Registers
|
||||||
reg [1:0] r_state_if;
|
reg [1:0] r_state_if;
|
||||||
reg [2:0] r_phase_count;
|
reg [2:0] r_phase_count;
|
||||||
reg r_cnt;
|
reg r_sync_input;
|
||||||
reg r_sync_input;
|
|
||||||
|
|
||||||
assign o_debug_state = r_state_if;
|
|
||||||
|
|
||||||
// Initial conditions
|
// Initial conditions
|
||||||
initial begin
|
initial begin
|
||||||
r_state_if = state_idle;
|
r_state_if = state_idle;
|
||||||
r_phase_count = 3'b111;
|
r_phase_count = 3'b111;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Global Assignments
|
// Global Assignments
|
||||||
assign o_fifo_write_clk = i_ddr_clk;
|
assign o_fifo_write_clk = i_ddr_clk;
|
||||||
|
assign o_debug_state = r_state_if;
|
||||||
|
|
||||||
// Main Process
|
// Main Process
|
||||||
always @(posedge i_ddr_clk or negedge i_rst_b)
|
always @(posedge i_ddr_clk or negedge i_rst_b) begin
|
||||||
begin
|
if (i_rst_b == 1'b0) begin
|
||||||
if (i_rst_b == 1'b0) begin
|
r_state_if <= state_idle;
|
||||||
r_state_if <= state_idle;
|
o_fifo_push <= 1'b0;
|
||||||
o_fifo_push <= 1'b0;
|
r_phase_count <= 3'b111;
|
||||||
r_phase_count <= 3'b111;
|
r_sync_input <= 1'b0;
|
||||||
r_cnt <= 0;
|
end else begin
|
||||||
r_sync_input <= 1'b0;
|
case (r_state_if)
|
||||||
end else begin
|
state_idle: begin
|
||||||
case (r_state_if)
|
if (i_ddr_data == modem_i_sync) begin
|
||||||
state_idle: begin
|
r_state_if <= state_i_phase;
|
||||||
if (i_ddr_data == modem_i_sync) begin
|
o_fifo_data <= {30'b000000000000000000000000000000, i_ddr_data};
|
||||||
r_state_if <= state_i_phase;
|
r_sync_input <= i_sync_input; // mark the sync input for this sample
|
||||||
o_fifo_data <= {30'b000000000000000000000000000000, i_ddr_data};
|
end
|
||||||
r_sync_input <= i_sync_input; // mark the sync input for this sample
|
r_phase_count <= 3'b111;
|
||||||
end
|
o_fifo_push <= 1'b0;
|
||||||
r_phase_count <= 3'b111;
|
|
||||||
o_fifo_push <= 1'b0;
|
|
||||||
end
|
|
||||||
|
|
||||||
state_i_phase: begin
|
|
||||||
if (r_phase_count == 3'b000) begin
|
|
||||||
if (i_ddr_data == modem_q_sync ) begin
|
|
||||||
r_phase_count <= 3'b110;
|
|
||||||
r_state_if <= state_q_phase;
|
|
||||||
end else begin
|
|
||||||
r_state_if <= state_idle;
|
|
||||||
end
|
|
||||||
end else begin
|
|
||||||
r_phase_count <= r_phase_count - 1;
|
|
||||||
end
|
|
||||||
|
|
||||||
o_fifo_push <= 1'b0;
|
|
||||||
o_fifo_data <= {o_fifo_data[29:0], i_ddr_data};
|
|
||||||
end
|
|
||||||
|
|
||||||
state_q_phase: begin
|
|
||||||
if (r_phase_count == 3'b000) begin
|
|
||||||
o_fifo_push <= ~i_fifo_full;
|
|
||||||
r_state_if <= state_idle;
|
|
||||||
o_fifo_data <= {o_fifo_data[29:0], i_ddr_data[1], r_sync_input};
|
|
||||||
end else begin
|
|
||||||
o_fifo_push <= 1'b0;
|
|
||||||
r_phase_count <= r_phase_count - 1;
|
|
||||||
o_fifo_data <= {o_fifo_data[29:0], i_ddr_data};
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
endcase
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
state_i_phase: begin
|
||||||
|
if (r_phase_count == 3'b000) begin
|
||||||
|
if (i_ddr_data == modem_q_sync) begin
|
||||||
|
r_phase_count <= 3'b110;
|
||||||
|
r_state_if <= state_q_phase;
|
||||||
|
end else begin
|
||||||
|
r_state_if <= state_idle;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
r_phase_count <= r_phase_count - 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
o_fifo_push <= 1'b0;
|
||||||
|
o_fifo_data <= {o_fifo_data[29:0], i_ddr_data};
|
||||||
|
end
|
||||||
|
|
||||||
|
state_q_phase: begin
|
||||||
|
if (r_phase_count == 3'b000) begin
|
||||||
|
o_fifo_push <= ~i_fifo_full;
|
||||||
|
r_state_if <= state_idle;
|
||||||
|
o_fifo_data <= {o_fifo_data[29:0], i_ddr_data[1], r_sync_input};
|
||||||
|
end else begin
|
||||||
|
o_fifo_push <= 1'b0;
|
||||||
|
r_phase_count <= r_phase_count - 1;
|
||||||
|
o_fifo_data <= {o_fifo_data[29:0], i_ddr_data};
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
endcase
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -1,43 +1,52 @@
|
||||||
module lvds_tx
|
module lvds_tx (
|
||||||
(
|
input i_rst_b,
|
||||||
input i_rst_b,
|
input i_ddr_clk,
|
||||||
input i_ddr_clk,
|
output [1:0] o_ddr_data,
|
||||||
output [1:0] o_ddr_data,
|
|
||||||
|
|
||||||
input i_fifo_empty,
|
input i_fifo_empty,
|
||||||
output o_fifo_read_clk,
|
output o_fifo_read_clk,
|
||||||
output o_fifo_pull,
|
output reg o_fifo_pull,
|
||||||
input [31:0] i_fifo_data,
|
input [31:0] i_fifo_data,
|
||||||
input i_sync_input,
|
input i_tx_state,
|
||||||
output [1:0] o_debug_state );
|
input i_sync_input,
|
||||||
|
output [ 1:0] o_debug_state
|
||||||
|
);
|
||||||
|
|
||||||
// Internal Registers
|
// Internal Registers
|
||||||
reg [4:0] r_phase_count;
|
reg [ 4:0] r_phase_count;
|
||||||
|
reg [31:0] r_fifo_data;
|
||||||
|
|
||||||
// Initial conditions
|
// Initial conditions
|
||||||
initial begin
|
initial begin
|
||||||
r_phase_count = 5'b11111;
|
r_phase_count = 5'd31;
|
||||||
end
|
end
|
||||||
|
|
||||||
assign o_fifo_read_clk = i_ddr_clk;
|
assign o_fifo_read_clk = i_ddr_clk;
|
||||||
|
|
||||||
|
|
||||||
// Main Process / shift register
|
|
||||||
always @(posedge i_ddr_clk)
|
// Main Process / shift register
|
||||||
begin
|
always @(posedge i_ddr_clk) begin
|
||||||
if (i_rst_b == 1'b0) begin
|
if (i_rst_b == 1'b0) begin
|
||||||
o_fifo_pull <= ~i_fifo_empty;
|
o_fifo_pull <= 1'b0;
|
||||||
r_phase_count <= 5'b11111;
|
r_phase_count <= 5'd31;
|
||||||
|
r_fifo_data <= 32'b00000000000000000000000000000000;
|
||||||
|
end else begin
|
||||||
|
if (r_phase_count == 5'd3) begin
|
||||||
|
o_fifo_pull <= ~i_fifo_empty;
|
||||||
|
end else if (r_phase_count == 5'd1) begin
|
||||||
|
if (i_tx_state) begin
|
||||||
|
r_fifo_data <= i_fifo_data;
|
||||||
end else begin
|
end else begin
|
||||||
if (r_phase_count == 5'b00001) begin
|
r_fifo_data <= 32'b00000000000000000000000000000000;
|
||||||
o_fifo_pull <= ~i_fifo_empty;
|
|
||||||
end else begin
|
|
||||||
o_fifo_pull <= 1'b0;
|
|
||||||
end
|
|
||||||
|
|
||||||
o_ddr_data <= i_fifo_data[r_phase_count:r_phase_count-1];
|
|
||||||
r_phase_count <= r_phase_count - 2;
|
|
||||||
end
|
end
|
||||||
end
|
o_fifo_pull <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
o_fifo_pull <= 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
endmodule
|
o_ddr_data <= r_fifo_data[r_phase_count:r_phase_count-1];
|
||||||
|
r_phase_count <= r_phase_count - 2;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -1,54 +1,63 @@
|
||||||
module smi_ctrl
|
module smi_ctrl
|
||||||
(
|
(
|
||||||
input i_rst_b,
|
input i_rst_b,
|
||||||
input i_sys_clk, // FPGA Clock
|
input i_sys_clk, // FPGA Clock
|
||||||
input i_fast_clk,
|
input i_fast_clk,
|
||||||
|
|
||||||
input [4:0] i_ioc,
|
input [4:0] i_ioc,
|
||||||
input [7:0] i_data_in,
|
input [7:0] i_data_in,
|
||||||
output reg [7:0] o_data_out,
|
output reg [7:0] o_data_out,
|
||||||
input i_cs,
|
input i_cs,
|
||||||
input i_fetch_cmd,
|
input i_fetch_cmd,
|
||||||
input i_load_cmd,
|
input i_load_cmd,
|
||||||
|
|
||||||
// FIFO INTERFACE
|
|
||||||
output o_fifo_pull,
|
|
||||||
input [31:0] i_fifo_pulled_data,
|
|
||||||
input i_fifo_full,
|
|
||||||
input i_fifo_empty,
|
|
||||||
|
|
||||||
// SMI INTERFACE
|
// FIFO INTERFACE
|
||||||
input i_smi_soe_se,
|
output o_rx_fifo_pull,
|
||||||
input i_smi_swe_srw,
|
input [31:0] i_rx_fifo_pulled_data,
|
||||||
output reg [7:0] o_smi_data_out,
|
input i_rx_fifo_empty,
|
||||||
input [7:0] i_smi_data_in,
|
output o_tx_fifo_push,
|
||||||
output o_smi_read_req,
|
output reg [31:0] o_tx_fifo_pushed_data,
|
||||||
output o_smi_write_req,
|
input i_tx_fifo_full,
|
||||||
input i_smi_test,
|
output o_tx_fifo_clock,
|
||||||
output o_channel,
|
|
||||||
|
|
||||||
// Errors
|
|
||||||
output reg o_address_error);
|
|
||||||
|
|
||||||
|
// SMI INTERFACE
|
||||||
|
input i_smi_soe_se,
|
||||||
|
input i_smi_swe_srw,
|
||||||
|
output reg [7:0] o_smi_data_out,
|
||||||
|
input [7:0] i_smi_data_in,
|
||||||
|
output o_smi_read_req,
|
||||||
|
output o_smi_write_req,
|
||||||
|
input i_smi_test,
|
||||||
|
output o_channel,
|
||||||
|
|
||||||
|
// TX CONDITIONAL
|
||||||
|
output reg o_cond_tx,
|
||||||
|
// Errors
|
||||||
|
output reg o_address_error);
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
|
||||||
// MODULE SPECIFIC IOC LIST
|
// MODULE SPECIFIC IOC LIST
|
||||||
// ------------------------
|
// ---------------------------------
|
||||||
localparam
|
localparam
|
||||||
ioc_module_version = 5'b00000, // read only
|
ioc_module_version = 5'b00000, // read only
|
||||||
ioc_fifo_status = 5'b00001, // read-only
|
ioc_fifo_status = 5'b00001, // read-only
|
||||||
ioc_channel_select = 5'b00010;
|
ioc_channel_select = 5'b00010;
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
// MODULE SPECIFIC PARAMS
|
// MODULE SPECIFIC PARAMS
|
||||||
// ----------------------
|
// ---------------------------------
|
||||||
localparam
|
localparam
|
||||||
module_version = 8'b00000001;
|
module_version = 8'b00000001;
|
||||||
|
|
||||||
|
// ---------------------------------------
|
||||||
|
// MODULE CONTROL
|
||||||
|
// ---------------------------------------
|
||||||
|
assign o_channel = r_channel;
|
||||||
always @(posedge i_sys_clk or negedge i_rst_b)
|
always @(posedge i_sys_clk or negedge i_rst_b)
|
||||||
begin
|
begin
|
||||||
if (i_rst_b == 1'b0) begin
|
if (i_rst_b == 1'b0) begin
|
||||||
o_address_error <= 1'b0;
|
o_address_error <= 1'b0;
|
||||||
w_channel <= 1'b0;
|
|
||||||
end else begin
|
end else begin
|
||||||
if (i_cs == 1'b1) begin
|
if (i_cs == 1'b1) begin
|
||||||
//=============================================
|
//=============================================
|
||||||
|
@ -61,9 +70,11 @@ module smi_ctrl
|
||||||
|
|
||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
ioc_fifo_status: begin
|
ioc_fifo_status: begin
|
||||||
o_data_out[0] <= i_fifo_empty;
|
o_data_out[0] <= i_rx_fifo_empty;
|
||||||
o_data_out[1] <= r_channel;
|
o_data_out[1] <= i_tx_fifo_full;
|
||||||
o_data_out[7:2] <= 6'b000000;
|
o_data_out[2] <= r_channel;
|
||||||
|
o_data_out[3] <= i_smi_test;
|
||||||
|
o_data_out[7:4] <= 4'b0000;
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
@ -82,29 +93,32 @@ module smi_ctrl
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// Tell the RPI that data is pending in either of the two fifos
|
|
||||||
assign o_smi_read_req = (!i_fifo_empty) || i_smi_test;
|
// ---------------------------------------
|
||||||
reg [4:0] int_cnt;
|
// RX SIDE
|
||||||
|
// ---------------------------------------
|
||||||
|
reg [4:0] int_cnt_rx;
|
||||||
|
reg [7:0] r_smi_test_count;
|
||||||
reg r_fifo_pull;
|
reg r_fifo_pull;
|
||||||
reg r_fifo_pull_1;
|
reg r_fifo_pull_1;
|
||||||
wire w_fifo_pull_trigger;
|
wire w_fifo_pull_trigger;
|
||||||
reg r_channel;
|
reg r_channel;
|
||||||
assign o_channel = r_channel;
|
|
||||||
reg [7:0] r_smi_test_count;
|
|
||||||
reg [31:0] r_fifo_pulled_data;
|
reg [31:0] r_fifo_pulled_data;
|
||||||
|
|
||||||
wire soe_and_reset;
|
wire soe_and_reset;
|
||||||
assign soe_and_reset = i_rst_b & i_smi_soe_se;
|
assign soe_and_reset = i_rst_b & i_smi_soe_se;
|
||||||
|
assign o_smi_read_req = (!i_rx_fifo_empty) || i_smi_test;
|
||||||
|
assign o_rx_fifo_pull = !r_fifo_pull_1 && r_fifo_pull && !i_rx_fifo_empty;
|
||||||
|
|
||||||
always @(negedge soe_and_reset)
|
always @(negedge soe_and_reset)
|
||||||
begin
|
begin
|
||||||
if (i_rst_b == 1'b0) begin
|
if (i_rst_b == 1'b0) begin
|
||||||
int_cnt <= 5'd31;
|
int_cnt_rx <= 5'd0;
|
||||||
r_smi_test_count <= 8'h56;
|
r_smi_test_count <= 8'h56;
|
||||||
r_fifo_pulled_data <= 32'h00000000;
|
r_fifo_pulled_data <= 32'h00000000;
|
||||||
end else begin
|
end else begin
|
||||||
// trigger the fifo pulling on the second byte
|
// trigger the fifo pulling on the second byte
|
||||||
w_fifo_pull_trigger <= (int_cnt == 5'd23) && !i_smi_test;
|
w_fifo_pull_trigger <= (int_cnt_rx == 5'd8) && !i_smi_test;
|
||||||
|
|
||||||
if ( i_smi_test ) begin
|
if ( i_smi_test ) begin
|
||||||
if (r_smi_test_count == 0) begin
|
if (r_smi_test_count == 0) begin
|
||||||
|
@ -114,12 +128,12 @@ module smi_ctrl
|
||||||
r_smi_test_count <= {((r_smi_test_count[2] ^ r_smi_test_count[3]) & 1'b1), r_smi_test_count[7:1]};
|
r_smi_test_count <= {((r_smi_test_count[2] ^ r_smi_test_count[3]) & 1'b1), r_smi_test_count[7:1]};
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
int_cnt <= int_cnt - 8;
|
int_cnt_rx <= int_cnt_rx + 8;
|
||||||
o_smi_data_out <= r_fifo_pulled_data[int_cnt:int_cnt-7];
|
o_smi_data_out <= r_fifo_pulled_data[int_cnt_rx+7:int_cnt_rx];
|
||||||
|
|
||||||
// update the internal register as soon as we reach the fourth byte
|
// update the internal register as soon as we reach the fourth byte
|
||||||
if (int_cnt == 5'd7) begin
|
if (int_cnt_rx == 5'd24) begin
|
||||||
r_fifo_pulled_data <= i_fifo_pulled_data;
|
r_fifo_pulled_data <= i_rx_fifo_pulled_data;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -137,6 +151,113 @@ module smi_ctrl
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assign o_fifo_pull = !r_fifo_pull_1 && r_fifo_pull && !i_fifo_empty;
|
// -----------------------------------------
|
||||||
|
// TX SIDE
|
||||||
|
// -----------------------------------------
|
||||||
|
localparam
|
||||||
|
tx_state_first = 2'b00,
|
||||||
|
tx_state_second = 2'b01,
|
||||||
|
tx_state_third = 2'b10,
|
||||||
|
tx_state_fourth = 2'b11;
|
||||||
|
|
||||||
|
reg [4:0] int_cnt_tx;
|
||||||
|
reg [31:0] r_fifo_pushed_data;
|
||||||
|
reg [1:0] tx_reg_state;
|
||||||
|
reg modem_tx_ctrl;
|
||||||
|
reg cond_tx_ctrl;
|
||||||
|
reg r_fifo_push;
|
||||||
|
reg r_fifo_push_1;
|
||||||
|
wire w_fifo_push_trigger;
|
||||||
|
assign o_smi_write_req = !i_tx_fifo_full;
|
||||||
|
assign o_tx_fifo_push = !r_fifo_push_1 && r_fifo_push && !i_tx_fifo_full;
|
||||||
|
assign swe_and_reset = i_rst_b & i_smi_swe_srw;
|
||||||
|
assign o_tx_fifo_clock = i_sys_clk;
|
||||||
|
|
||||||
|
always @(negedge swe_and_reset)
|
||||||
|
begin
|
||||||
|
if (i_rst_b == 1'b0) begin
|
||||||
|
tx_reg_state <= tx_state_first;
|
||||||
|
w_fifo_push_trigger <= 1'b0;
|
||||||
|
r_fifo_pushed_data <= 32'h00000000;
|
||||||
|
modem_tx_ctrl <= 1'b0;
|
||||||
|
cond_tx_ctrl <= 1'b0;
|
||||||
|
//cnt <= 0;
|
||||||
|
end else begin
|
||||||
|
case (tx_reg_state)
|
||||||
|
//----------------------------------------------
|
||||||
|
tx_state_first:
|
||||||
|
begin
|
||||||
|
if (i_smi_data_in[7] == 1'b1) begin
|
||||||
|
r_fifo_pushed_data[31:30] <= 2'b10;
|
||||||
|
modem_tx_ctrl <= i_smi_data_in[6];
|
||||||
|
cond_tx_ctrl <= i_smi_data_in[5];
|
||||||
|
r_fifo_pushed_data[29:25] <= i_smi_data_in[4:0];
|
||||||
|
tx_reg_state <= tx_state_second;
|
||||||
|
w_fifo_push_trigger <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
// if from some reason we are in the first byte stage and we got
|
||||||
|
// a byte without '1' on its MSB, that means that we are not synced
|
||||||
|
// so push a "sync" word into the modem.
|
||||||
|
cond_tx_ctrl <= 1'b0;
|
||||||
|
modem_tx_ctrl <= 1'b0;
|
||||||
|
o_tx_fifo_pushed_data <= 32'h00000000;
|
||||||
|
w_fifo_push_trigger <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
//----------------------------------------------
|
||||||
|
tx_state_second:
|
||||||
|
begin
|
||||||
|
if (i_smi_data_in[7] == 1'b0) begin
|
||||||
|
r_fifo_pushed_data[24:18] <= i_smi_data_in[6:0];
|
||||||
|
tx_reg_state <= tx_state_third;
|
||||||
|
end else begin
|
||||||
|
tx_reg_state <= tx_state_first;
|
||||||
|
end
|
||||||
|
w_fifo_push_trigger <= 1'b0;
|
||||||
|
end
|
||||||
|
//----------------------------------------------
|
||||||
|
tx_state_third:
|
||||||
|
begin
|
||||||
|
if (i_smi_data_in[7] == 1'b0) begin
|
||||||
|
r_fifo_pushed_data[17] <= i_smi_data_in[6];
|
||||||
|
r_fifo_pushed_data[16] <= modem_tx_ctrl;
|
||||||
|
r_fifo_pushed_data[15:14] <= 2'b01;
|
||||||
|
r_fifo_pushed_data[13:8] <= i_smi_data_in[5:0];
|
||||||
|
tx_reg_state <= tx_state_fourth;
|
||||||
|
end else begin
|
||||||
|
tx_reg_state <= tx_state_first;
|
||||||
|
end
|
||||||
|
w_fifo_push_trigger <= 1'b0;
|
||||||
|
end
|
||||||
|
//----------------------------------------------
|
||||||
|
tx_state_fourth:
|
||||||
|
begin
|
||||||
|
if (i_smi_data_in[7] == 1'b0) begin
|
||||||
|
o_tx_fifo_pushed_data <= {r_fifo_pushed_data[31:8], i_smi_data_in[6:0], 1'b0};
|
||||||
|
//o_tx_fifo_pushed_data <= {2'b10, cnt, 1'b1, 2'b01, 13'h3F, 1'b0};
|
||||||
|
//o_tx_fifo_pushed_data <= {cnt, cnt, 6'b111111};
|
||||||
|
//cnt <= cnt + 1024;
|
||||||
|
w_fifo_push_trigger <= 1'b1;
|
||||||
|
o_cond_tx <= cond_tx_ctrl;
|
||||||
|
end else begin
|
||||||
|
o_tx_fifo_pushed_data <= 32'h00000000;
|
||||||
|
w_fifo_push_trigger <= 1'b0;
|
||||||
|
end
|
||||||
|
tx_reg_state <= tx_state_first;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge i_sys_clk)
|
||||||
|
begin
|
||||||
|
if (i_rst_b == 1'b0) begin
|
||||||
|
r_fifo_push <= 1'b0;
|
||||||
|
r_fifo_push_1 <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
r_fifo_push <= w_fifo_push_trigger;
|
||||||
|
r_fifo_push_1 <= r_fifo_push;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
endmodule // smi_ctrl
|
endmodule // smi_ctrl
|
|
@ -1,114 +1,110 @@
|
||||||
`include "spi_slave.v"
|
`include "spi_slave.v"
|
||||||
|
|
||||||
module spi_if
|
module spi_if (
|
||||||
(
|
input i_rst_b, // FPGA Reset
|
||||||
input i_rst_b, // FPGA Reset
|
input i_sys_clk, // FPGA Clock
|
||||||
input i_sys_clk, // FPGA Clock
|
|
||||||
|
|
||||||
output reg [4:0] o_ioc,
|
output reg [4:0] o_ioc,
|
||||||
output reg [7:0] o_data_in, // data that was received over SPI
|
output reg [7:0] o_data_in, // data that was received over SPI
|
||||||
input [7:0] i_data_out, // data to be sent over the SPI
|
input [7:0] i_data_out, // data to be sent over the SPI
|
||||||
output reg [3:0] o_cs,
|
output reg [3:0] o_cs,
|
||||||
output reg o_fetch_cmd,
|
output reg o_fetch_cmd,
|
||||||
output reg o_load_cmd,
|
output reg o_load_cmd,
|
||||||
|
|
||||||
// SPI Interface
|
// SPI Interface
|
||||||
input i_spi_sck,
|
input i_spi_sck,
|
||||||
output o_spi_miso,
|
output o_spi_miso,
|
||||||
input i_spi_mosi,
|
input i_spi_mosi,
|
||||||
input i_spi_cs_b );
|
input i_spi_cs_b
|
||||||
|
);
|
||||||
|
|
||||||
localparam
|
localparam
|
||||||
state_idle = 3'b000,
|
state_idle = 3'b000,
|
||||||
state_fetch1 = 3'b001,
|
state_fetch1 = 3'b001,
|
||||||
state_fetch2 = 3'b010,
|
state_fetch2 = 3'b010,
|
||||||
state_load = 3'b011,
|
state_load = 3'b011,
|
||||||
state_post_op= 3'b100;
|
state_post_op= 3'b100;
|
||||||
|
|
||||||
reg [2:0] state_if;
|
// internal registers / wires
|
||||||
wire w_rx_data_valid;
|
reg [2:0] state_if;
|
||||||
wire [7:0] w_rx_data;
|
wire w_rx_data_valid;
|
||||||
reg r_tx_data_valid;
|
wire [7:0] w_rx_data;
|
||||||
reg [7:0] r_tx_byte;
|
reg r_tx_data_valid;
|
||||||
|
reg [7:0] r_tx_byte;
|
||||||
|
|
||||||
reg [4:0] r_ioc;
|
reg [4:0] r_ioc;
|
||||||
reg [7:0] r_data;
|
reg [7:0] r_data;
|
||||||
|
|
||||||
// Initial conditions
|
// Initial conditions
|
||||||
initial begin
|
initial begin
|
||||||
state_if = state_idle;
|
state_if = state_idle;
|
||||||
end
|
end
|
||||||
|
|
||||||
spi_slave spi
|
spi_slave spi (
|
||||||
(
|
.i_sys_clk (i_sys_clk),
|
||||||
.i_sys_clk (i_sys_clk),
|
.o_rx_data_valid(w_rx_data_valid),
|
||||||
.o_rx_data_valid (w_rx_data_valid),
|
.o_rx_byte (w_rx_data),
|
||||||
.o_rx_byte (w_rx_data),
|
.i_tx_data_valid(r_tx_data_valid),
|
||||||
.i_tx_data_valid (r_tx_data_valid),
|
.i_tx_byte (r_tx_byte),
|
||||||
.i_tx_byte (r_tx_byte),
|
|
||||||
|
|
||||||
.i_spi_sck (i_spi_sck),
|
.i_spi_sck (i_spi_sck),
|
||||||
.o_spi_miso (o_spi_miso),
|
.o_spi_miso(o_spi_miso),
|
||||||
.i_spi_mosi (i_spi_mosi),
|
.i_spi_mosi(i_spi_mosi),
|
||||||
.i_spi_cs_b (i_spi_cs_b)
|
.i_spi_cs_b(i_spi_cs_b)
|
||||||
);
|
);
|
||||||
|
|
||||||
always @(posedge i_sys_clk)
|
always @(posedge i_sys_clk) begin
|
||||||
begin
|
if (i_rst_b == 1'b0) begin
|
||||||
if (i_rst_b == 1'b0) begin
|
state_if <= state_idle;
|
||||||
state_if <= state_idle;
|
end else if (w_rx_data_valid == 1'b1) begin
|
||||||
// whenever a new byte arrives
|
// whenever a new byte arrives
|
||||||
end else if (w_rx_data_valid == 1'b1) begin
|
case (state_if)
|
||||||
case (state_if)
|
//----------------------------------
|
||||||
//----------------------------------
|
state_idle: begin
|
||||||
state_idle:
|
o_ioc = w_rx_data[4:0];
|
||||||
begin
|
case (w_rx_data[6:5])
|
||||||
o_ioc = w_rx_data[4:0];
|
2'b00: o_cs <= 4'b0001;
|
||||||
case(w_rx_data[6:5])
|
2'b01: o_cs <= 4'b0010;
|
||||||
2'b00: o_cs <= 4'b0001;
|
2'b10: o_cs <= 4'b0100;
|
||||||
2'b01: o_cs <= 4'b0010;
|
2'b11: o_cs <= 4'b1000;
|
||||||
2'b10: o_cs <= 4'b0100;
|
endcase
|
||||||
2'b11: o_cs <= 4'b1000;
|
|
||||||
endcase
|
|
||||||
|
|
||||||
if (w_rx_data[7] == 1'b1) begin // write command
|
if (w_rx_data[7] == 1'b1) begin // write command
|
||||||
state_if <= state_load;
|
state_if <= state_load;
|
||||||
end else begin // read command
|
end else begin // read command
|
||||||
o_fetch_cmd <= 1'b1;
|
o_fetch_cmd <= 1'b1;
|
||||||
state_if <= state_fetch1;
|
state_if <= state_fetch1;
|
||||||
end
|
end
|
||||||
|
|
||||||
o_load_cmd <= 1'b0;
|
o_load_cmd <= 1'b0;
|
||||||
r_tx_data_valid <= 1'b0;
|
r_tx_data_valid <= 1'b0;
|
||||||
end
|
|
||||||
//----------------------------------
|
|
||||||
state_load:
|
|
||||||
begin
|
|
||||||
o_data_in <= w_rx_data;
|
|
||||||
o_load_cmd <= 1'b1;
|
|
||||||
state_if <= state_idle;
|
|
||||||
end
|
|
||||||
//----------------------------------
|
|
||||||
state_post_op:
|
|
||||||
begin
|
|
||||||
o_fetch_cmd <= 1'b0;
|
|
||||||
o_load_cmd <= 1'b0;
|
|
||||||
state_if <= state_idle;
|
|
||||||
end
|
|
||||||
endcase
|
|
||||||
end else begin
|
|
||||||
if (state_if == state_fetch1) begin
|
|
||||||
o_fetch_cmd <= 1'b0;
|
|
||||||
state_if <= state_fetch2;
|
|
||||||
end else if (state_if == state_fetch2) begin
|
|
||||||
r_tx_byte <= i_data_out;
|
|
||||||
r_tx_data_valid <= 1'b1;
|
|
||||||
state_if <= state_post_op;
|
|
||||||
end else begin
|
|
||||||
o_load_cmd <= 1'b0;
|
|
||||||
r_tx_data_valid <= 1'b0;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
//----------------------------------
|
||||||
|
state_load: begin
|
||||||
|
o_data_in <= w_rx_data;
|
||||||
|
o_load_cmd <= 1'b1;
|
||||||
|
state_if <= state_idle;
|
||||||
|
end
|
||||||
|
//----------------------------------
|
||||||
|
state_post_op: begin
|
||||||
|
o_fetch_cmd <= 1'b0;
|
||||||
|
o_load_cmd <= 1'b0;
|
||||||
|
state_if <= state_idle;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end else begin
|
||||||
|
if (state_if == state_fetch1) begin
|
||||||
|
o_fetch_cmd <= 1'b0;
|
||||||
|
state_if <= state_fetch2;
|
||||||
|
end else if (state_if == state_fetch2) begin
|
||||||
|
r_tx_byte <= i_data_out;
|
||||||
|
r_tx_data_valid <= 1'b1;
|
||||||
|
state_if <= state_post_op;
|
||||||
|
end else begin
|
||||||
|
o_load_cmd <= 1'b0;
|
||||||
|
r_tx_data_valid <= 1'b0;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
endmodule // spi_if
|
|
||||||
|
end
|
||||||
|
endmodule // spi_if
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
module spi_slave
|
module spi_slave (
|
||||||
#(parameter SPI_MODE = 0)
|
|
||||||
(
|
|
||||||
// Control/Data Signals,
|
// Control/Data Signals,
|
||||||
input i_sys_clk, // FPGA Clock
|
input i_sys_clk, // FPGA Clock
|
||||||
output reg o_rx_data_valid, // Data Valid pulse (1 clock cycle)
|
output reg o_rx_data_valid, // Data Valid pulse (1 clock cycle)
|
||||||
output reg [7:0] o_rx_byte, // Byte received on MOSI
|
output reg [7:0] o_rx_byte, // Byte received on MOSI
|
||||||
input i_tx_data_valid, // Data Valid pulse to register i_tx_byte
|
input i_tx_data_valid, // Data Valid pulse to register i_tx_byte
|
||||||
input [7:0] i_tx_byte, // Byte to serialize to MISO.
|
input [7:0] i_tx_byte, // Byte to serialize to MISO.
|
||||||
|
|
||||||
// SPI Interface
|
// SPI Interface
|
||||||
input i_spi_sck,
|
input i_spi_sck,
|
||||||
output reg o_spi_miso,
|
output reg o_spi_miso,
|
||||||
input i_spi_mosi,
|
input i_spi_mosi,
|
||||||
input i_spi_cs_b );
|
input i_spi_cs_b
|
||||||
|
);
|
||||||
|
|
||||||
reg [2:0] r_rx_bit_count;
|
reg [2:0] r_rx_bit_count;
|
||||||
reg [2:0] r_tx_bit_count;
|
reg [2:0] r_tx_bit_count;
|
||||||
|
@ -25,8 +24,7 @@ module spi_slave
|
||||||
|
|
||||||
// Purpose: Recover SPI Byte in SPI Clock Domain
|
// Purpose: Recover SPI Byte in SPI Clock Domain
|
||||||
// Samples line on correct edge of SPI Clock
|
// Samples line on correct edge of SPI Clock
|
||||||
always @(posedge i_spi_sck/* or posedge i_spi_cs_b*/)
|
always @(posedge i_spi_sck /* or posedge i_spi_cs_b*/) begin
|
||||||
begin
|
|
||||||
if (i_spi_cs_b) begin
|
if (i_spi_cs_b) begin
|
||||||
r_rx_bit_count <= 0;
|
r_rx_bit_count <= 0;
|
||||||
r_rx_done <= 1'b0;
|
r_rx_done <= 1'b0;
|
||||||
|
@ -42,35 +40,18 @@ module spi_slave
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
/*always @(posedge i_sys_clk)
|
|
||||||
begin
|
|
||||||
if (i_spi_cs_b) begin
|
|
||||||
r_rx_bit_count <= 0;
|
|
||||||
r_rx_done <= 1'b0;
|
|
||||||
end else if (SCK_risingedge) begin
|
|
||||||
r_rx_bit_count <= r_rx_bit_count + 1;
|
|
||||||
r_temp_rx_byte <= {r_temp_rx_byte[6:0], i_spi_mosi};
|
|
||||||
|
|
||||||
if (r_rx_bit_count == 3'b111) begin
|
|
||||||
r_rx_done <= 1'b1;
|
|
||||||
r_rx_byte <= {r_temp_rx_byte[6:0], i_spi_mosi};
|
|
||||||
end else if (r_rx_bit_count == 3'b010) begin
|
|
||||||
r_rx_done <= 1'b0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end*/
|
|
||||||
|
|
||||||
// Purpose: Cross from SPI Clock Domain to main FPGA clock domain
|
// Purpose: Cross from SPI Clock Domain to main FPGA clock domain
|
||||||
// Assert o_rx_data_valid for 1 clock cycle when o_rx_byte has valid data.
|
// Assert o_rx_data_valid for 1 clock cycle when o_rx_byte has valid data.
|
||||||
always @(posedge i_sys_clk)
|
always @(posedge i_sys_clk) begin
|
||||||
begin
|
|
||||||
// Here is where clock domains are crossed.
|
// Here is where clock domains are crossed.
|
||||||
// This will require timing constraint created, can set up long path.
|
// This will require timing constraint created, can set up long path.
|
||||||
r2_rx_done <= r_rx_done;
|
r2_rx_done <= r_rx_done;
|
||||||
r3_rx_done <= r2_rx_done;
|
r3_rx_done <= r2_rx_done;
|
||||||
if (r3_rx_done == 1'b0 && r2_rx_done == 1'b1) begin // rising edge
|
if (r3_rx_done == 1'b0 && r2_rx_done == 1'b1) begin // rising edge
|
||||||
o_rx_data_valid <= 1'b1; // Pulse Data Valid 1 clock cycle
|
o_rx_data_valid <= 1'b1; // Pulse Data Valid 1 clock cycle
|
||||||
o_rx_byte <= r_rx_byte;
|
o_rx_byte <= r_rx_byte;
|
||||||
end else begin
|
end else begin
|
||||||
o_rx_data_valid <= 1'b0;
|
o_rx_data_valid <= 1'b0;
|
||||||
|
@ -79,13 +60,12 @@ module spi_slave
|
||||||
|
|
||||||
reg [2:0] SCKr;
|
reg [2:0] SCKr;
|
||||||
always @(posedge i_sys_clk) SCKr <= {SCKr[1:0], i_spi_sck};
|
always @(posedge i_sys_clk) SCKr <= {SCKr[1:0], i_spi_sck};
|
||||||
wire SCK_risingedge = (SCKr[2:1]==2'b01); // now we can detect SCK rising edges
|
wire SCK_risingedge = (SCKr[2:1] == 2'b01); // now we can detect SCK rising edges
|
||||||
|
|
||||||
// Purpose: Transmits 1 SPI Byte whenever SPI clock is toggling
|
// Purpose: Transmits 1 SPI Byte whenever SPI clock is toggling
|
||||||
// Will transmit read data back to SW over MISO line.
|
// Will transmit read data back to SW over MISO line.
|
||||||
// Want to put data on the line immediately when CS goes low.
|
// Want to put data on the line immediately when CS goes low.
|
||||||
always @(posedge i_sys_clk)
|
always @(posedge i_sys_clk) begin
|
||||||
begin
|
|
||||||
if (i_spi_cs_b || i_tx_data_valid) begin
|
if (i_spi_cs_b || i_tx_data_valid) begin
|
||||||
r_tx_byte <= i_tx_byte;
|
r_tx_byte <= i_tx_byte;
|
||||||
r_tx_bit_count <= 3'b110;
|
r_tx_bit_count <= 3'b110;
|
||||||
|
@ -102,4 +82,4 @@ module spi_slave
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endmodule // SPI_Slave
|
endmodule // SPI_Slave
|
||||||
|
|
794
firmware/top.v
794
firmware/top.v
|
@ -3,365 +3,511 @@
|
||||||
`include "io_ctrl.v"
|
`include "io_ctrl.v"
|
||||||
`include "smi_ctrl.v"
|
`include "smi_ctrl.v"
|
||||||
`include "lvds_rx.v"
|
`include "lvds_rx.v"
|
||||||
|
`include "lvds_tx.v"
|
||||||
`include "complex_fifo.v"
|
`include "complex_fifo.v"
|
||||||
|
|
||||||
module top( input i_glob_clock,
|
module top (
|
||||||
input i_rst_b, // i_smi_a1
|
input i_glob_clock,
|
||||||
|
input i_rst_b, // i_smi_a1
|
||||||
// RF FRONT-END PATH
|
|
||||||
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_rx_lna,
|
|
||||||
output o_shdn_tx_lna,
|
|
||||||
|
|
||||||
// MODEM (LVDS & CLOCK)
|
// RF FRONT-END PATH
|
||||||
output o_iq_tx_p,
|
output o_rx_h_tx_l,
|
||||||
output o_iq_tx_n,
|
output o_rx_h_tx_l_b,
|
||||||
output o_iq_tx_clk_p,
|
output o_tr_vc1,
|
||||||
output o_iq_tx_clk_n,
|
output o_tr_vc1_b,
|
||||||
input i_iq_rx_09_p, // Paired with i_iq_rx_09_n - only the 'B' pins need to be specified
|
output o_tr_vc2,
|
||||||
input i_iq_rx_24_n, // Paired with i_iq_rx_24_p - only the 'B' pins need to be specified
|
output o_shdn_rx_lna,
|
||||||
input i_iq_rx_clk_p, // Paired with i_iq_rx_clk_n - only the 'B' pins need to be specified
|
output o_shdn_tx_lna,
|
||||||
|
|
||||||
// Note: The icestorm (specifically nextpnr) fails to build if both diff pins are constrained
|
// MODEM (LVDS & CLOCK)
|
||||||
// in the constrain file and the interface herein. Thus we need to take them out so that
|
output o_iq_tx_p,
|
||||||
// it will "understand" we actually want an LVDS pair inputs. In addition, the pair is
|
output o_iq_tx_n,
|
||||||
// defined only by the "B" pins in BANK3 and not the "A" pins (which is counter-logical)
|
output o_iq_tx_clk_p,
|
||||||
|
output o_iq_tx_clk_n,
|
||||||
|
input i_iq_rx_09_p, // Paired with i_iq_rx_09_n - only the 'B' pins need to be specified
|
||||||
|
input i_iq_rx_24_n, // Paired with i_iq_rx_24_p - only the 'B' pins need to be specified
|
||||||
|
input i_iq_rx_clk_p, // Paired with i_iq_rx_clk_n - only the 'B' pins need to be specified
|
||||||
|
|
||||||
// MIXER
|
// Note: The icestorm (specifically nextpnr) fails to build if both diff pins are constrained
|
||||||
output o_mixer_fm,
|
// in the constrain file and the interface herein. Thus we need to take them out so that
|
||||||
output o_mixer_en,
|
// it will "understand" we actually want an LVDS pair inputs. In addition, the pair is
|
||||||
|
// defined only by the "B" pins in BANK3 and not the "A" pins (which is counter-logical)
|
||||||
|
|
||||||
// DIGITAL I/F
|
// MIXER
|
||||||
input [3:0] i_config,
|
output o_mixer_fm,
|
||||||
input i_button,
|
output o_mixer_en,
|
||||||
inout [7:0] io_pmod,
|
|
||||||
output o_led0,
|
|
||||||
output o_led1,
|
|
||||||
|
|
||||||
// SMI Addressing description
|
// DIGITAL I/F
|
||||||
// ==========================
|
input [3:0] i_config,
|
||||||
// In CaribouLite, the SMI addresses are connected as follows:
|
input i_button,
|
||||||
//
|
inout [7:0] io_pmod,
|
||||||
// RPI PIN | FPGA TOP-LEVEL SIGNAL
|
output o_led0,
|
||||||
// ------------------------------------------------------------------------
|
output o_led1,
|
||||||
// GPIO2_SA3 | i_smi_a[2] - RX09 / RX24 channel select
|
|
||||||
// GPIO3_SA2 | i_smi_a[1] - Tx SMI (0) / Rx SMI (1) select
|
|
||||||
// GPIO4_SA1 | i_smi_a[0] - used as a sys async reset (GBIN1)
|
|
||||||
// GPIO5_SA0 | Not connected to FPGA (MixerRst)
|
|
||||||
//
|
|
||||||
// In order to perform SMI data bus direction selection (highZ / PushPull)
|
|
||||||
// signal a[0] was chosen, while the '0' level (default) denotes RPI => FPGA
|
|
||||||
// direction, and the DATA bus is highZ (recessive mode).
|
|
||||||
// The signal a[2] selects the RX source (900 MHZ or 2.4GHz)
|
|
||||||
// The signal a[1] can be used in the future for other purposes
|
|
||||||
//
|
|
||||||
// Description | a[2] (SA3)| a[1] (SA2) |
|
|
||||||
// -------------|------------|---------------|
|
|
||||||
// | 0 | 0 |
|
|
||||||
// TX |------------| RPI => FPGA |
|
|
||||||
// | 1 | Data HighZ |
|
|
||||||
// -------------|------------|---------------|
|
|
||||||
// RX09 | 0 | 1 |
|
|
||||||
// -------------|------------| FPGA => RPI |
|
|
||||||
// RX24 | 1 | Data PushPull |
|
|
||||||
// -------------|------------|---------------|
|
|
||||||
input i_smi_a2,
|
|
||||||
input i_smi_a3,
|
|
||||||
|
|
||||||
input i_smi_soe_se,
|
// SMI Addressing description
|
||||||
input i_smi_swe_srw,
|
// ==========================
|
||||||
inout [7:0] io_smi_data,
|
// In CaribouLite, the SMI addresses are connected as follows:
|
||||||
output o_smi_write_req,
|
//
|
||||||
output o_smi_read_req,
|
// RPI PIN | FPGA TOP-LEVEL SIGNAL
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// GPIO2_SA3 | i_smi_a[2] - RX09 / RX24 channel select
|
||||||
|
// GPIO3_SA2 | i_smi_a[1] - Tx SMI (0) / Rx SMI (1) select
|
||||||
|
// GPIO4_SA1 | i_smi_a[0] - used as a sys async reset (GBIN1)
|
||||||
|
// GPIO5_SA0 | Not connected to FPGA (MixerRst)
|
||||||
|
//
|
||||||
|
// In order to perform SMI data bus direction selection (highZ / PushPull)
|
||||||
|
// signal a[0] was chosen, while the '0' level (default) denotes RPI => FPGA
|
||||||
|
// direction, and the DATA bus is highZ (recessive mode).
|
||||||
|
// The signal a[2] selects the RX source (900 MHZ or 2.4GHz)
|
||||||
|
// The signal a[1] can be used in the future for other purposes
|
||||||
|
//
|
||||||
|
// Description | a[2] (SA3)| a[1] (SA2) |
|
||||||
|
// -------------|------------|---------------|
|
||||||
|
// | 0 | 0 |
|
||||||
|
// TX |------------| RPI => FPGA |
|
||||||
|
// | 1 | Data HighZ |
|
||||||
|
// -------------|------------|---------------|
|
||||||
|
// RX09 | 0 | 1 |
|
||||||
|
// -------------|------------| FPGA => RPI |
|
||||||
|
// RX24 | 1 | Data PushPull |
|
||||||
|
// -------------|------------|---------------|
|
||||||
|
input i_smi_a2,
|
||||||
|
input i_smi_a3,
|
||||||
|
|
||||||
// SPI
|
input i_smi_soe_se,
|
||||||
input i_mosi,
|
input i_smi_swe_srw,
|
||||||
input i_sck,
|
inout [7:0] io_smi_data,
|
||||||
input i_ss,
|
output o_smi_write_req,
|
||||||
output o_miso
|
output o_smi_read_req,
|
||||||
);
|
|
||||||
|
// SPI
|
||||||
|
input i_mosi,
|
||||||
|
input i_sck,
|
||||||
|
input i_ss,
|
||||||
|
output o_miso
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// INNER SIGNALS
|
// INNER SIGNALS
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
reg r_counter;
|
reg r_counter;
|
||||||
wire w_clock_spi;
|
wire w_clock_spi;
|
||||||
wire w_clock_sys;
|
wire w_clock_sys;
|
||||||
wire [4:0] w_ioc;
|
wire [4:0] w_ioc;
|
||||||
wire [7:0] w_rx_data;
|
wire [7:0] w_rx_data;
|
||||||
reg [7:0] r_tx_data;
|
reg [7:0] r_tx_data;
|
||||||
wire [3:0] w_cs;
|
wire [3:0] w_cs;
|
||||||
wire w_fetch;
|
wire w_fetch;
|
||||||
wire w_load;
|
wire w_load;
|
||||||
|
|
||||||
wire [7:0] w_tx_data_sys;
|
wire [7:0] w_tx_data_sys;
|
||||||
wire [7:0] w_tx_data_io;
|
wire [7:0] w_tx_data_io;
|
||||||
wire [7:0] w_tx_data_smi;
|
wire [7:0] w_tx_data_smi;
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// INSTANCES
|
// INSTANCES
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
spi_if spi_if_ins
|
spi_if spi_if_ins (
|
||||||
(
|
.i_rst_b(i_rst_b),
|
||||||
.i_rst_b (i_rst_b),
|
.i_sys_clk(w_clock_sys),
|
||||||
.i_sys_clk (w_clock_sys),
|
.o_ioc(w_ioc),
|
||||||
.o_ioc (w_ioc),
|
.o_data_in(w_rx_data),
|
||||||
.o_data_in (w_rx_data),
|
.i_data_out(r_tx_data),
|
||||||
.i_data_out (r_tx_data),
|
.o_cs(w_cs),
|
||||||
.o_cs (w_cs),
|
.o_fetch_cmd(w_fetch),
|
||||||
.o_fetch_cmd (w_fetch),
|
.o_load_cmd(w_load),
|
||||||
.o_load_cmd (w_load),
|
|
||||||
|
|
||||||
// SPI Interface
|
// SPI Interface
|
||||||
.i_spi_sck (i_sck),
|
.i_spi_sck (i_sck),
|
||||||
.o_spi_miso (int_miso),
|
.o_spi_miso(int_miso),
|
||||||
.i_spi_mosi (i_mosi),
|
.i_spi_mosi(i_mosi),
|
||||||
.i_spi_cs_b (i_ss)
|
.i_spi_cs_b(i_ss)
|
||||||
);
|
);
|
||||||
|
|
||||||
wire int_miso;
|
wire int_miso;
|
||||||
assign o_miso = (i_ss)?1'bZ:int_miso;
|
assign o_miso = (i_ss) ? 1'bZ : int_miso;
|
||||||
|
|
||||||
// SYSTEM CTRL
|
// SYSTEM CTRL
|
||||||
sys_ctrl sys_ctrl_ins
|
sys_ctrl sys_ctrl_ins (
|
||||||
(
|
.i_rst_b(i_rst_b),
|
||||||
.i_rst_b (i_rst_b),
|
.i_sys_clk(w_clock_sys),
|
||||||
.i_sys_clk (w_clock_sys),
|
.i_ioc(w_ioc),
|
||||||
.i_ioc (w_ioc),
|
.i_data_in(w_rx_data),
|
||||||
.i_data_in (w_rx_data),
|
.o_data_out(w_tx_data_sys),
|
||||||
.o_data_out (w_tx_data_sys),
|
.i_cs(w_cs[0]),
|
||||||
.i_cs (w_cs[0]),
|
.i_fetch_cmd(w_fetch),
|
||||||
.i_fetch_cmd (w_fetch),
|
.i_load_cmd(w_load),
|
||||||
.i_load_cmd (w_load),
|
|
||||||
|
|
||||||
.i_error_list (8'b00000000),
|
.i_error_list(8'b00000000),
|
||||||
.o_debug_fifo_push (w_debug_fifo_push),
|
.o_debug_fifo_push(w_debug_fifo_push),
|
||||||
.o_debug_fifo_pull (w_debug_fifo_pull),
|
.o_debug_fifo_pull(w_debug_fifo_pull),
|
||||||
.o_debug_smi_test (w_debug_smi_test)
|
.o_debug_smi_test(w_debug_smi_test),
|
||||||
);
|
);
|
||||||
|
|
||||||
wire w_debug_fifo_push;
|
wire w_debug_fifo_push;
|
||||||
wire w_debug_fifo_pull;
|
wire w_debug_fifo_pull;
|
||||||
wire w_debug_smi_test;
|
wire w_debug_smi_test;
|
||||||
|
|
||||||
// IO CTRL
|
|
||||||
io_ctrl io_ctrl_ins
|
|
||||||
(
|
|
||||||
.i_rst_b (i_rst_b),
|
|
||||||
.i_sys_clk (w_clock_sys),
|
|
||||||
.i_ioc (w_ioc),
|
|
||||||
.i_data_in (w_rx_data),
|
|
||||||
.o_data_out (w_tx_data_io),
|
|
||||||
.i_cs (w_cs[1]),
|
|
||||||
.i_fetch_cmd (w_fetch),
|
|
||||||
.i_load_cmd (w_load),
|
|
||||||
|
|
||||||
// Digital interfaces
|
// IO CTRL
|
||||||
.i_button (i_button),
|
io_ctrl io_ctrl_ins (
|
||||||
.i_config (i_config),
|
.i_rst_b(i_rst_b),
|
||||||
.o_led0 (o_led0),
|
.i_sys_clk(w_clock_sys),
|
||||||
.o_led1 (o_led1),
|
.i_ioc(w_ioc),
|
||||||
.o_pmod (),
|
.i_data_in(w_rx_data),
|
||||||
|
.o_data_out(w_tx_data_io),
|
||||||
|
.i_cs(w_cs[1]),
|
||||||
|
.i_fetch_cmd(w_fetch),
|
||||||
|
.i_load_cmd(w_load),
|
||||||
|
|
||||||
// Analog interfaces
|
// Digital interfaces
|
||||||
.o_mixer_fm (o_mixer_fm),
|
.i_button(i_button),
|
||||||
.o_rx_h_tx_l (o_rx_h_tx_l),
|
.i_config(i_config),
|
||||||
.o_rx_h_tx_l_b (o_rx_h_tx_l_b),
|
.o_led0 (o_led0),
|
||||||
.o_tr_vc1 (o_tr_vc1),
|
.o_led1 (o_led1),
|
||||||
.o_tr_vc1_b (o_tr_vc1_b),
|
.o_pmod (),
|
||||||
.o_tr_vc2 (o_tr_vc2),
|
|
||||||
.o_shdn_tx_lna (o_shdn_tx_lna),
|
|
||||||
.o_shdn_rx_lna (o_shdn_rx_lna),
|
|
||||||
.o_mixer_en (o_mixer_en)
|
|
||||||
);
|
|
||||||
|
|
||||||
//=========================================================================
|
// Analog interfaces
|
||||||
// CLOCK AND DATA-FLOW
|
.o_mixer_fm(o_mixer_fm),
|
||||||
//=========================================================================
|
.o_rx_h_tx_l(o_rx_h_tx_l),
|
||||||
assign w_clock_sys = r_counter;
|
.o_rx_h_tx_l_b(o_rx_h_tx_l_b),
|
||||||
|
.o_tr_vc1(o_tr_vc1),
|
||||||
|
.o_tr_vc1_b(o_tr_vc1_b),
|
||||||
|
.o_tr_vc2(o_tr_vc2),
|
||||||
|
.o_shdn_tx_lna(o_shdn_tx_lna),
|
||||||
|
.o_shdn_rx_lna(o_shdn_rx_lna),
|
||||||
|
.o_mixer_en(o_mixer_en)
|
||||||
|
);
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// CLOCK AND DATA-FLOW
|
// CONBINATORIAL ASSIGNMENTS
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
always @(posedge i_glob_clock)
|
assign w_clock_sys = r_counter;
|
||||||
begin
|
|
||||||
if (i_rst_b == 1'b0) begin
|
|
||||||
r_counter <= 1'b0;
|
|
||||||
end else begin
|
|
||||||
r_counter <= !r_counter;
|
|
||||||
|
|
||||||
case (w_cs)
|
//=========================================================================
|
||||||
4'b0001: r_tx_data <= w_tx_data_sys;
|
// CLOCK AND DATA-FLOW
|
||||||
4'b0010: r_tx_data <= w_tx_data_io;
|
//=========================================================================
|
||||||
4'b0100: r_tx_data <= w_tx_data_smi;
|
always @(posedge i_glob_clock) begin
|
||||||
4'b1000: r_tx_data <= 8'b10100101; // 0xA5: reserved
|
if (i_rst_b == 1'b0) begin
|
||||||
4'b0000: r_tx_data <= 8'b00000000; // no module selected
|
r_counter <= 1'b0;
|
||||||
endcase
|
end else begin
|
||||||
end
|
r_counter <= !r_counter;
|
||||||
end
|
|
||||||
|
|
||||||
//=========================================================================
|
case (w_cs)
|
||||||
// I/O (SB_IO, SB_GB) DIFFERENTIAL LINES
|
4'b0001: r_tx_data <= w_tx_data_sys;
|
||||||
//=========================================================================
|
4'b0010: r_tx_data <= w_tx_data_io;
|
||||||
|
4'b0100: r_tx_data <= w_tx_data_smi;
|
||||||
|
4'b1000: r_tx_data <= 8'b10100101; // 0xA5: reserved
|
||||||
|
4'b0000: r_tx_data <= 8'b00000000; // no module selected
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
// Differential clock signal (DDR)
|
//=========================================================================
|
||||||
wire lvds_clock; // The direct clock input
|
// I/O (SB_IO, SB_GB) DIFFERENTIAL LINES
|
||||||
wire lvds_clock_buf; // The clock input after global buffer (improved fanout)
|
//=========================================================================
|
||||||
|
|
||||||
SB_IO #(.PIN_TYPE(6'b000001), // Input only, direct mode
|
//---------------------------------------------
|
||||||
.IO_STANDARD("SB_LVDS_INPUT")) // LVDS input
|
// LVDS CLOCK
|
||||||
iq_rx_clk ( .PACKAGE_PIN(i_iq_rx_clk_p), // Physical connection to 'i_iq_rx_clk_p'
|
//---------------------------------------------
|
||||||
.D_IN_0 ( lvds_clock )); // Wire out to 'lvds_clock'
|
// Differential clock signal (DDR)
|
||||||
|
wire lvds_clock; // The direct clock input
|
||||||
|
wire lvds_clock_buf; // The clock input after global buffer (improved fanout)
|
||||||
|
|
||||||
assign lvds_clock_buf = lvds_clock;
|
SB_IO #(
|
||||||
|
.PIN_TYPE (6'b000001), // Input only, direct mode
|
||||||
|
.IO_STANDARD("SB_LVDS_INPUT")
|
||||||
|
) // LVDS input
|
||||||
|
iq_rx_clk (
|
||||||
|
.PACKAGE_PIN(i_iq_rx_clk_p), // Physical connection to 'i_iq_rx_clk_p'
|
||||||
|
.D_IN_0(lvds_clock)
|
||||||
|
); // Wire out to 'lvds_clock'
|
||||||
|
|
||||||
|
assign lvds_clock_buf = lvds_clock;
|
||||||
|
|
||||||
|
//---------------------------------------------
|
||||||
|
// LVDS RX - I/Q Data
|
||||||
|
//---------------------------------------------
|
||||||
|
|
||||||
|
// Differential 2.4GHz I/Q DDR signal
|
||||||
|
SB_IO #(
|
||||||
|
.PIN_TYPE (6'b000000), // Input only, DDR mode (sample on both pos edge and
|
||||||
|
// negedge of the input clock)
|
||||||
|
.IO_STANDARD("SB_LVDS_INPUT"), // LVDS standard
|
||||||
|
.NEG_TRIGGER(1'b0)
|
||||||
|
) // The signal is not negated
|
||||||
|
iq_rx_24 (
|
||||||
|
.PACKAGE_PIN(i_iq_rx_24_n), // Attention: this is the 'n' input, thus the actual values
|
||||||
|
// will need to be negated (PCB layout constraint)
|
||||||
|
.INPUT_CLK(lvds_clock_buf), // The I/O sampling clock with DDR
|
||||||
|
.D_IN_0(w_lvds_rx_24_d0), // the 0 deg data output
|
||||||
|
.D_IN_1(w_lvds_rx_24_d1)
|
||||||
|
); // the 180 deg data output
|
||||||
|
|
||||||
|
|
||||||
// Differential 2.4GHz I/Q DDR signal
|
// Differential 0.9GHz I/Q DDR signal
|
||||||
SB_IO #(.PIN_TYPE(6'b000000), // Input only, DDR mode (sample on both pos edge and
|
SB_IO #(
|
||||||
// negedge of the input clock)
|
.PIN_TYPE (6'b000000), // Input only, DDR mode (sample on both pos edge and
|
||||||
.IO_STANDARD("SB_LVDS_INPUT"), // LVDS standard
|
// negedge of the input clock)
|
||||||
.NEG_TRIGGER(1'b0)) // The signal is not negated
|
.IO_STANDARD("SB_LVDS_INPUT"), // LVDS standard
|
||||||
iq_rx_24 ( .PACKAGE_PIN(i_iq_rx_24_n), // Attention: this is the 'n' input, thus the actual values
|
.NEG_TRIGGER(1'b0)
|
||||||
// will need to be negated (PCB layout constraint)
|
) // The signal is negated in hardware
|
||||||
.INPUT_CLK (lvds_clock_buf), // The I/O sampling clock with DDR
|
iq_rx_09 (
|
||||||
.D_IN_0 ( w_lvds_rx_24_d1 ), // the 0 deg data output
|
.PACKAGE_PIN(i_iq_rx_09_p),
|
||||||
.D_IN_1 ( w_lvds_rx_24_d0 )); // the 180 deg data output
|
.INPUT_CLK(lvds_clock_buf), // The I/O sampling clock with DDR
|
||||||
|
.D_IN_0(w_lvds_rx_09_d0), // the 0 deg data output
|
||||||
|
.D_IN_1(w_lvds_rx_09_d1)
|
||||||
|
); // the 180 deg data output
|
||||||
|
|
||||||
|
//----------------------------------------------
|
||||||
|
// LVDS TX - I/Q Data
|
||||||
|
//----------------------------------------------
|
||||||
|
|
||||||
|
// Non-inverting, P-side of pair
|
||||||
|
SB_IO #(
|
||||||
|
.PIN_TYPE (6'b010000), // {PIN_OUTPUT_DDR, PIN_INPUT_REGISTER }
|
||||||
|
.IO_STANDARD("SB_LVCMOS"),
|
||||||
|
) iq_tx_p (
|
||||||
|
.PACKAGE_PIN(o_iq_tx_p),
|
||||||
|
.OUTPUT_CLK(lvds_clock_buf),
|
||||||
|
.D_OUT_0(~w_lvds_tx_d1),
|
||||||
|
.D_OUT_1(~w_lvds_tx_d0)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Inverting, N-side of pair
|
||||||
|
SB_IO #(
|
||||||
|
.PIN_TYPE (6'b010000), // {PIN_OUTPUT_DDR, PIN_INPUT_REGISTER }
|
||||||
|
.IO_STANDARD("SB_LVCMOS"),
|
||||||
|
) iq_tx_n (
|
||||||
|
.PACKAGE_PIN(o_iq_tx_n),
|
||||||
|
.OUTPUT_CLK(lvds_clock_buf),
|
||||||
|
.D_OUT_0(w_lvds_tx_d1),
|
||||||
|
.D_OUT_1(w_lvds_tx_d0)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign o_iq_tx_clk_p = lvds_clock_buf;
|
||||||
|
assign o_iq_tx_clk_n = ~lvds_clock_buf;
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
// LVDS RX SIGNAL FROM MODEM
|
||||||
|
//=========================================================================
|
||||||
|
wire w_lvds_rx_09_d0; // 0 degree
|
||||||
|
wire w_lvds_rx_09_d1; // 180 degree
|
||||||
|
wire w_lvds_rx_24_d0; // 0 degree
|
||||||
|
wire w_lvds_rx_24_d1; // 180 degree
|
||||||
|
|
||||||
|
wire w_lvds_tx_d0; // 0 degree
|
||||||
|
wire w_lvds_tx_d1; // 180 degree
|
||||||
|
|
||||||
|
// RX FIFO Internals
|
||||||
|
wire w_rx_09_fifo_write_clk;
|
||||||
|
wire w_rx_09_fifo_push;
|
||||||
|
wire [31:0] w_rx_09_fifo_data;
|
||||||
|
|
||||||
|
wire w_rx_24_fifo_write_clk;
|
||||||
|
wire w_rx_24_fifo_push;
|
||||||
|
wire [31:0] w_rx_24_fifo_data;
|
||||||
|
|
||||||
|
lvds_rx lvds_rx_09_inst (
|
||||||
|
.i_rst_b (i_rst_b),
|
||||||
|
.i_ddr_clk(lvds_clock_buf),
|
||||||
|
|
||||||
|
.i_ddr_data({w_lvds_rx_09_d0, w_lvds_rx_09_d1}),
|
||||||
|
|
||||||
|
.i_fifo_full(w_rx_fifo_full),
|
||||||
|
.o_fifo_write_clk(w_rx_09_fifo_write_clk),
|
||||||
|
.o_fifo_push(w_rx_09_fifo_push),
|
||||||
|
|
||||||
|
.o_fifo_data (w_rx_09_fifo_data),
|
||||||
|
.i_sync_input (1'b0),
|
||||||
|
.o_debug_state()
|
||||||
|
);
|
||||||
|
|
||||||
|
lvds_rx lvds_rx_24_inst (
|
||||||
|
.i_rst_b (i_rst_b),
|
||||||
|
.i_ddr_clk(lvds_clock_buf),
|
||||||
|
|
||||||
|
.i_ddr_data({w_lvds_rx_24_d0, w_lvds_rx_24_d1}),
|
||||||
|
|
||||||
|
.i_fifo_full(w_rx_fifo_full),
|
||||||
|
.o_fifo_write_clk(w_rx_24_fifo_write_clk),
|
||||||
|
.o_fifo_push(w_rx_24_fifo_push),
|
||||||
|
|
||||||
|
.o_fifo_data (w_rx_24_fifo_data),
|
||||||
|
.i_sync_input (1'b0),
|
||||||
|
.o_debug_state()
|
||||||
|
);
|
||||||
|
|
||||||
|
wire w_rx_fifo_write_clk = (channel == 1'b0) ? w_rx_09_fifo_write_clk : w_rx_24_fifo_write_clk;
|
||||||
|
wire w_rx_fifo_push = (channel == 1'b0) ? w_rx_09_fifo_push : w_rx_24_fifo_push;
|
||||||
|
wire [31:0] w_rx_fifo_data = (channel == 1'b0) ? w_rx_09_fifo_data : w_rx_24_fifo_data;
|
||||||
|
wire w_rx_fifo_pull;
|
||||||
|
wire [31:0] w_rx_fifo_pulled_data;
|
||||||
|
wire w_rx_fifo_full;
|
||||||
|
wire w_rx_fifo_empty;
|
||||||
|
wire channel;
|
||||||
|
|
||||||
|
|
||||||
// Differential 0.9GHz I/Q DDR signal
|
complex_fifo rx_fifo (
|
||||||
SB_IO #(.PIN_TYPE(6'b000000), // Input only, DDR mode (sample on both pos edge and
|
.wr_rst_b_i(i_rst_b),
|
||||||
// negedge of the input clock)
|
.wr_clk_i(w_rx_fifo_write_clk),
|
||||||
.IO_STANDARD("SB_LVDS_INPUT"), // LVDS standard
|
.wr_en_i(w_rx_fifo_push),
|
||||||
.NEG_TRIGGER(1'b0)) // The signal is negated in hardware
|
.wr_data_i(w_rx_fifo_data),
|
||||||
iq_rx_09 ( .PACKAGE_PIN(i_iq_rx_09_p),
|
.rd_rst_b_i(i_rst_b),
|
||||||
.INPUT_CLK (lvds_clock_buf), // The I/O sampling clock with DDR
|
.rd_clk_i(w_clock_sys),
|
||||||
.D_IN_0 ( w_lvds_rx_09_d1 ), // the 0 deg data output
|
.rd_en_i(w_rx_fifo_pull),
|
||||||
.D_IN_1 ( w_lvds_rx_09_d0 ) ); // the 180 deg data output
|
.rd_data_o(w_rx_fifo_pulled_data),
|
||||||
|
.full_o(w_rx_fifo_full),
|
||||||
|
.empty_o(w_rx_fifo_empty),
|
||||||
|
.debug_pull(w_debug_fifo_pull),
|
||||||
|
.debug_push(w_debug_fifo_push)
|
||||||
|
);
|
||||||
|
complex_fifo tx_fifo (
|
||||||
|
// smi clock is writing
|
||||||
|
.wr_rst_b_i(i_rst_b),
|
||||||
|
.wr_clk_i(w_tx_fifo_clock),
|
||||||
|
.wr_en_i(w_tx_fifo_push),
|
||||||
|
.wr_data_i(w_tx_fifo_data),
|
||||||
|
|
||||||
|
// lvds clock is pulling (reading)
|
||||||
|
.rd_rst_b_i(i_rst_b),
|
||||||
|
.rd_clk_i(w_tx_fifo_read_clk),
|
||||||
|
.rd_en_i(w_tx_fifo_pull),
|
||||||
|
.rd_data_o(w_tx_fifo_pulled_data),
|
||||||
|
.full_o(w_tx_fifo_full),
|
||||||
|
.empty_o(w_tx_fifo_empty),
|
||||||
|
.debug_pull(1'b0),
|
||||||
|
.debug_push(1'b0)
|
||||||
|
);
|
||||||
|
|
||||||
|
smi_ctrl smi_ctrl_ins (
|
||||||
|
.i_rst_b(i_rst_b),
|
||||||
|
.i_sys_clk(w_clock_sys),
|
||||||
|
.i_fast_clk(i_glob_clock),
|
||||||
|
.i_ioc(w_ioc),
|
||||||
|
.i_data_in(w_rx_data),
|
||||||
|
.o_data_out(w_tx_data_smi),
|
||||||
|
.i_cs(w_cs[2]),
|
||||||
|
.i_fetch_cmd(w_fetch),
|
||||||
|
.i_load_cmd(w_load),
|
||||||
|
|
||||||
//=========================================================================
|
// FIFO RX
|
||||||
// LVDS RX SIGNAL FROM MODEM
|
.o_rx_fifo_pull(w_rx_fifo_pull),
|
||||||
//=========================================================================
|
.i_rx_fifo_pulled_data(w_rx_fifo_pulled_data),
|
||||||
wire w_lvds_rx_09_d0; // 0 degree
|
.i_rx_fifo_empty(w_rx_fifo_empty),
|
||||||
wire w_lvds_rx_09_d1; // 180 degree
|
// FIFO TX
|
||||||
wire w_lvds_rx_24_d0; // 0 degree
|
.o_tx_fifo_push(w_tx_fifo_push),
|
||||||
wire w_lvds_rx_24_d1; // 180 degree
|
.o_tx_fifo_pushed_data(w_tx_fifo_data),
|
||||||
|
.i_tx_fifo_full(w_tx_fifo_full),
|
||||||
|
.o_tx_fifo_clock(w_tx_fifo_clock),
|
||||||
|
|
||||||
wire w_rx_09_fifo_write_clk;
|
.i_smi_soe_se(i_smi_soe_se),
|
||||||
wire w_rx_09_fifo_push;
|
.i_smi_swe_srw(i_smi_swe_srw),
|
||||||
wire [31:0] w_rx_09_fifo_data;
|
.o_smi_data_out(w_smi_data_output),
|
||||||
|
.i_smi_data_in(w_smi_data_input),
|
||||||
|
.o_smi_read_req(w_smi_read_req),
|
||||||
|
.o_smi_write_req(w_smi_write_req),
|
||||||
|
.o_channel(channel),
|
||||||
|
.i_smi_test(w_debug_smi_test),
|
||||||
|
.o_address_error()
|
||||||
|
);
|
||||||
|
|
||||||
wire w_rx_24_fifo_write_clk;
|
wire [7:0] w_smi_data_output;
|
||||||
wire w_rx_24_fifo_push;
|
wire [7:0] w_smi_data_input;
|
||||||
wire [31:0] w_rx_24_fifo_data;
|
wire w_smi_read_req;
|
||||||
|
wire w_smi_write_req;
|
||||||
|
|
||||||
lvds_rx lvds_rx_09_inst
|
// the "Writing" flag indicates that the data[7:0] direction (inout)
|
||||||
(
|
// from the FPGA's SMI module should be "output". This happens when the
|
||||||
.i_rst_b (i_rst_b),
|
// SMI is in the READ mode - data flows from the FPGA to the RPI (RX mode)
|
||||||
.i_ddr_clk (lvds_clock_buf),
|
// The address has the MSB '1' when in RX mode. otherwise (when IDLE or TX)
|
||||||
|
// the data is high-z, which is the more "recessive" mode
|
||||||
|
SB_IO #(
|
||||||
|
.PIN_TYPE(6'b1010_01),
|
||||||
|
.PULLUP (1'b0)
|
||||||
|
) smi_io0 (
|
||||||
|
.PACKAGE_PIN(io_smi_data[0]),
|
||||||
|
.OUTPUT_ENABLE(i_smi_a2),
|
||||||
|
.D_OUT_0(w_smi_data_output[0]),
|
||||||
|
.D_IN_0(w_smi_data_input[0])
|
||||||
|
);
|
||||||
|
SB_IO #(
|
||||||
|
.PIN_TYPE(6'b1010_01),
|
||||||
|
.PULLUP (1'b0)
|
||||||
|
) smi_io1 (
|
||||||
|
.PACKAGE_PIN(io_smi_data[1]),
|
||||||
|
.OUTPUT_ENABLE(i_smi_a2),
|
||||||
|
.D_OUT_0(w_smi_data_output[1]),
|
||||||
|
.D_IN_0(w_smi_data_input[1])
|
||||||
|
);
|
||||||
|
SB_IO #(
|
||||||
|
.PIN_TYPE(6'b1010_01),
|
||||||
|
.PULLUP (1'b0)
|
||||||
|
) smi_io2 (
|
||||||
|
.PACKAGE_PIN(io_smi_data[2]),
|
||||||
|
.OUTPUT_ENABLE(i_smi_a2),
|
||||||
|
.D_OUT_0(w_smi_data_output[2]),
|
||||||
|
.D_IN_0(w_smi_data_input[2])
|
||||||
|
);
|
||||||
|
SB_IO #(
|
||||||
|
.PIN_TYPE(6'b1010_01),
|
||||||
|
.PULLUP (1'b0)
|
||||||
|
) smi_io3 (
|
||||||
|
.PACKAGE_PIN(io_smi_data[3]),
|
||||||
|
.OUTPUT_ENABLE(i_smi_a2),
|
||||||
|
.D_OUT_0(w_smi_data_output[3]),
|
||||||
|
.D_IN_0(w_smi_data_input[3])
|
||||||
|
);
|
||||||
|
SB_IO #(
|
||||||
|
.PIN_TYPE(6'b1010_01),
|
||||||
|
.PULLUP (1'b0)
|
||||||
|
) smi_io4 (
|
||||||
|
.PACKAGE_PIN(io_smi_data[4]),
|
||||||
|
.OUTPUT_ENABLE(i_smi_a2),
|
||||||
|
.D_OUT_0(w_smi_data_output[4]),
|
||||||
|
.D_IN_0(w_smi_data_input[4])
|
||||||
|
);
|
||||||
|
SB_IO #(
|
||||||
|
.PIN_TYPE(6'b1010_01),
|
||||||
|
.PULLUP (1'b0)
|
||||||
|
) smi_io5 (
|
||||||
|
.PACKAGE_PIN(io_smi_data[5]),
|
||||||
|
.OUTPUT_ENABLE(i_smi_a2),
|
||||||
|
.D_OUT_0(w_smi_data_output[5]),
|
||||||
|
.D_IN_0(w_smi_data_input[5])
|
||||||
|
);
|
||||||
|
SB_IO #(
|
||||||
|
.PIN_TYPE(6'b1010_01),
|
||||||
|
.PULLUP (1'b0)
|
||||||
|
) smi_io6 (
|
||||||
|
.PACKAGE_PIN(io_smi_data[6]),
|
||||||
|
.OUTPUT_ENABLE(i_smi_a2),
|
||||||
|
.D_OUT_0(w_smi_data_output[6]),
|
||||||
|
.D_IN_0(w_smi_data_input[6])
|
||||||
|
);
|
||||||
|
SB_IO #(
|
||||||
|
.PIN_TYPE(6'b1010_01),
|
||||||
|
.PULLUP (1'b0)
|
||||||
|
) smi_io7 (
|
||||||
|
.PACKAGE_PIN(io_smi_data[7]),
|
||||||
|
.OUTPUT_ENABLE(i_smi_a2),
|
||||||
|
.D_OUT_0(w_smi_data_output[7]),
|
||||||
|
.D_IN_0(w_smi_data_input[7])
|
||||||
|
);
|
||||||
|
//assign io_smi_data = (i_smi_a2)?w_smi_data_output:8'bZ;
|
||||||
|
//assign w_smi_data_input = io_smi_data;
|
||||||
|
// We need the 'o_smi_write_req' to be 1 only when the direction is TX
|
||||||
|
// (i_smi_a2 == 0) and the write fifo is not full
|
||||||
|
assign o_smi_read_req = (i_smi_a2) ? w_smi_read_req : w_smi_write_req;
|
||||||
|
assign o_smi_write_req = 1'bZ;
|
||||||
|
|
||||||
.i_ddr_data ({w_lvds_rx_09_d1, w_lvds_rx_09_d0}),
|
//assign io_pmod[0] = w_rx_fifo_push;
|
||||||
|
//assign io_pmod[1] = w_rx_fifo_pull;
|
||||||
|
//assign io_pmod[2] = w_smi_read_req;
|
||||||
|
//assign io_pmod[3] = w_rx_fifo_full;
|
||||||
|
//assign io_pmod[4] = w_rx_fifo_empty;
|
||||||
|
//assign io_pmod[5] = i_smi_a2;
|
||||||
|
//assign io_pmod[6] = channel;
|
||||||
|
//assign io_pmod[7] = ...;
|
||||||
|
|
||||||
.i_fifo_full (w_rx_fifo_full),
|
endmodule // top
|
||||||
.o_fifo_write_clk (w_rx_09_fifo_write_clk),
|
|
||||||
.o_fifo_push (w_rx_09_fifo_push),
|
|
||||||
|
|
||||||
.o_fifo_data (w_rx_09_fifo_data),
|
|
||||||
.i_sync_input (1'b0),
|
|
||||||
.o_debug_state ()
|
|
||||||
);
|
|
||||||
|
|
||||||
lvds_rx lvds_rx_24_inst
|
|
||||||
(
|
|
||||||
.i_rst_b (i_rst_b),
|
|
||||||
.i_ddr_clk (lvds_clock_buf),
|
|
||||||
|
|
||||||
.i_ddr_data ({!w_lvds_rx_24_d1, !w_lvds_rx_24_d0}),
|
|
||||||
|
|
||||||
.i_fifo_full (w_rx_fifo_full),
|
|
||||||
.o_fifo_write_clk (w_rx_24_fifo_write_clk),
|
|
||||||
.o_fifo_push (w_rx_24_fifo_push),
|
|
||||||
|
|
||||||
.o_fifo_data (w_rx_24_fifo_data),
|
|
||||||
.i_sync_input (1'b0),
|
|
||||||
.o_debug_state ()
|
|
||||||
);
|
|
||||||
|
|
||||||
wire w_rx_fifo_write_clk = (channel == 1'b0)?w_rx_09_fifo_write_clk:w_rx_24_fifo_write_clk;
|
|
||||||
wire w_rx_fifo_push = (channel == 1'b0)?w_rx_09_fifo_push:w_rx_24_fifo_push;
|
|
||||||
wire [31:0] w_rx_fifo_data = (channel == 1'b0)?w_rx_09_fifo_data:w_rx_24_fifo_data;
|
|
||||||
wire w_rx_fifo_pull;
|
|
||||||
wire [31:0] w_rx_fifo_pulled_data;
|
|
||||||
wire w_rx_fifo_full;
|
|
||||||
wire w_rx_fifo_empty;
|
|
||||||
wire channel;
|
|
||||||
|
|
||||||
|
|
||||||
complex_fifo rx_fifo(
|
|
||||||
.wr_rst_b_i (i_rst_b),
|
|
||||||
.wr_clk_i (w_rx_fifo_write_clk),
|
|
||||||
.wr_en_i (w_rx_fifo_push),
|
|
||||||
.wr_data_i (w_rx_fifo_data),
|
|
||||||
.rd_rst_b_i (i_rst_b),
|
|
||||||
.rd_clk_i (w_clock_sys),
|
|
||||||
.rd_en_i (w_rx_fifo_pull),
|
|
||||||
.rd_data_o (w_rx_fifo_pulled_data),
|
|
||||||
.full_o (w_rx_fifo_full),
|
|
||||||
.empty_o (w_rx_fifo_empty),
|
|
||||||
.debug_pull (w_debug_fifo_pull),
|
|
||||||
.debug_push (w_debug_fifo_push)
|
|
||||||
);
|
|
||||||
|
|
||||||
smi_ctrl smi_ctrl_ins
|
|
||||||
(
|
|
||||||
.i_rst_b (i_rst_b),
|
|
||||||
.i_sys_clk (w_clock_sys),
|
|
||||||
.i_fast_clk (i_glob_clock),
|
|
||||||
.i_ioc (w_ioc),
|
|
||||||
.i_data_in (w_rx_data),
|
|
||||||
.o_data_out (w_tx_data_smi),
|
|
||||||
.i_cs (w_cs[2]),
|
|
||||||
.i_fetch_cmd (w_fetch),
|
|
||||||
.i_load_cmd (w_load),
|
|
||||||
|
|
||||||
.o_fifo_pull (w_rx_fifo_pull),
|
|
||||||
.i_fifo_pulled_data (w_rx_fifo_pulled_data),
|
|
||||||
.i_fifo_full (w_rx_fifo_full),
|
|
||||||
.i_fifo_empty (w_rx_fifo_empty),
|
|
||||||
|
|
||||||
.i_smi_soe_se (i_smi_soe_se),
|
|
||||||
.i_smi_swe_srw (i_smi_swe_srw),
|
|
||||||
.o_smi_data_out (w_smi_data_output),
|
|
||||||
.i_smi_data_in (w_smi_data_input),
|
|
||||||
.o_smi_read_req (w_smi_read_req),
|
|
||||||
.o_smi_write_req (w_smi_write_req),
|
|
||||||
.o_channel (channel),
|
|
||||||
.i_smi_test (w_debug_smi_test),
|
|
||||||
.o_address_error ()
|
|
||||||
);
|
|
||||||
|
|
||||||
wire [7:0] w_smi_data_output;
|
|
||||||
wire [7:0] w_smi_data_input;
|
|
||||||
wire w_smi_read_req;
|
|
||||||
wire w_smi_write_req;
|
|
||||||
|
|
||||||
assign io_smi_data = (i_smi_a2)?w_smi_data_output:8'bZ;
|
|
||||||
assign w_smi_data_input = io_smi_data;
|
|
||||||
assign o_smi_write_req = w_smi_write_req;
|
|
||||||
assign o_smi_read_req = w_smi_read_req;
|
|
||||||
|
|
||||||
assign io_pmod[0] = w_rx_fifo_push;
|
|
||||||
assign io_pmod[1] = w_rx_fifo_pull;
|
|
||||||
assign io_pmod[2] = w_smi_read_req;
|
|
||||||
assign io_pmod[3] = w_rx_fifo_full;
|
|
||||||
assign io_pmod[4] = w_rx_fifo_empty;
|
|
||||||
assign io_pmod[5] = i_smi_a2;
|
|
||||||
assign io_pmod[6] = channel;
|
|
||||||
//assign io_pmod[7] = ...;
|
|
||||||
|
|
||||||
endmodule // top
|
|
||||||
|
|
Ładowanie…
Reference in New Issue