Skip to content

Commit

Permalink
I2C SFP port working
Browse files Browse the repository at this point in the history
  • Loading branch information
bluecmd committed Oct 6, 2019
1 parent 7e129fc commit f34ac31
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -10,7 +10,7 @@ clean:
rm -f fejkon.sof
rm -fr gen

fejkon.sof: ip/altera_fc_phy/fc_phy.qip fejkon.qsys de5net.sdc de5net.tcl
fejkon.sof: ip/altera_fc_phy/fc_phy.qip fejkon.qsys de5net.sdc de5net.tcl $(wildcard ip/*/*.sv)
(mkdir -p gen; cd gen; $(QPATH)/bin/quartus_sh -t ../quartus.tcl)
cp gen/output_files/fejkon.sof $@

Expand Down
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -85,6 +85,7 @@ Accesses need to be 4 byte wide.
| 2 | Read only | TX Fault |
| 3 | Read/Write | TX Disable |
| 4:5 | Read/Write | Rate Select |
| 6 | Read/Write | I2C Reset |

### MSI Interrupts

Expand Down
6 changes: 3 additions & 3 deletions fejkon_sfp.tcl
Expand Up @@ -14,7 +14,7 @@ set_instance_parameter_value clk {EXPLICIT_CLOCK_RATE} {0.0}
set_instance_parameter_value clk {NUM_CLOCK_OUTPUTS} {1}

add_instance i2c altera_avalon_i2c 19.1
set_instance_parameter_value i2c {FIFO_DEPTH} {4}
set_instance_parameter_value i2c {FIFO_DEPTH} {64}
set_instance_parameter_value i2c {USE_AV_ST} {0}

add_instance mm altera_avalon_mm_bridge 19.1
Expand Down Expand Up @@ -76,12 +76,12 @@ set_connection_parameter_value mm.m0/sfp.mm arbitrationPriority {1}
set_connection_parameter_value mm.m0/sfp.mm baseAddress {0x0000}
set_connection_parameter_value mm.m0/sfp.mm defaultConnection {0}

add_connection reset.out_reset i2c.reset_sink

add_connection reset.out_reset mm.reset

add_connection reset.out_reset sfp.reset

add_connection sfp.i2c_reset i2c.reset_sink

# interconnect requirements
set_interconnect_requirement {$system} {qsys_mm.clockCrossingAdapter} {HANDSHAKE}
set_interconnect_requirement {$system} {qsys_mm.enableEccProtection} {FALSE}
Expand Down
58 changes: 29 additions & 29 deletions ip/sfp_port/sfp_port.sv
Expand Up @@ -18,6 +18,7 @@
module sfp_port (
input wire clk, // clk.clk
input wire reset, // reset.reset
output wire i2c_reset, // i2c_reset.reset
input wire los, // sfp.los
input wire mod0_prsnt_n, // .prsnt_n
output wire tx_disable, // .txdis
Expand All @@ -39,44 +40,28 @@ module sfp_port (
input wire scl_oe
);

reg [7:0] rd_data;
reg [1:0] rd_response;
wire [7:0] rd_data;
wire [1:0] rd_response;

reg [1:0] wr_response;
wire [1:0] wr_response;

reg tx_disable_r;
reg [1:0] ratesel_r;
reg i2c_reset_r;
reg mod0_prsnt_n_r;

// Reader
always @(posedge clk or posedge reset)
begin
if (reset)
begin
rd_data <= 8'b0;
rd_response <= 2'b10;
end
else if (mm_read)
begin
// Status register
// TODO(bluecmd): Seems to be some delay here where state
// transitions lag one clock cycle, probably due to Avalon needing
// the data the same clock cycle or something?
if (mm_address == 4'h0)
begin
rd_data <= {2'b00, ratesel, tx_disable_r, tx_fault, los, ~mod0_prsnt_n};
rd_response <= 2'b00;
end
else
rd_response <= 2'b11;
end
end
assign rd_data = {1'b0, i2c_reset_r, ratesel, tx_disable_r, tx_fault, los, ~mod0_prsnt_n};
assign rd_response = mm_address == 4'h0 ? 2'b00 : 2'b11;

// Writer
always @(posedge clk or posedge reset)
begin
if (reset)
begin
wr_response <= 2'b10;
tx_disable_r <= 1;
ratesel_r <= 2'b00;
i2c_reset_r <= 0;
end
else if (mm_write)
begin
Expand All @@ -85,19 +70,34 @@ module sfp_port (
begin
tx_disable_r <= mm_writedata[3];
ratesel_r <= mm_writedata[5:4];
wr_response <= 2'b00;
i2c_reset_r <= mm_writedata[6];
end
else
wr_response <= 2'b11;
end
else
begin
// Only reset for one clock cycle
i2c_reset_r <= 0;
end
end

always @(posedge clk)
begin
mod0_prsnt_n_r <= mod0_prsnt_n;
end

assign wr_response = mm_address == 4'h0 ? 2'b00 : 2'b11;

assign ratesel = ratesel_r;
assign tx_disable = tx_disable_r;

assign mm_response = mm_read ? rd_response : wr_response ;
assign mm_readdata = rd_data;

// Reset the I2C core when:
// - the host tells us to (i2c_reset_r)
// - the system is being reset (rest)
// - a SFP module was just plugged in (mod0_prsnt_n 1->0)
assign i2c_reset = i2c_reset_r | reset | (~mod0_prsnt_n & mod0_prsnt_n_r);

// Altera I2C master bus driver
assign scl_in = mod1_scl;
Expand Down
21 changes: 19 additions & 2 deletions ip/sfp_port/sfp_port_hw.tcl
@@ -1,11 +1,11 @@
# TCL File Generated by Component Editor 19.1
# Thu Oct 03 22:48:40 CEST 2019
# Sun Oct 06 14:02:46 CEST 2019
# DO NOT MODIFY


#
# sfp_port "SFP Port" v1.0
# bluecmd 2019.10.03.22:48:40
# bluecmd 2019.10.06.14:02:46
#
#

Expand Down Expand Up @@ -158,3 +158,20 @@ add_interface_port i2c sda_oe sda_oe Input 1
add_interface_port i2c scl_in scl_in Output 1
add_interface_port i2c scl_oe scl_oe Input 1


#
# connection point i2c_reset
#
add_interface i2c_reset reset start
set_interface_property i2c_reset associatedClock clk
set_interface_property i2c_reset associatedDirectReset ""
set_interface_property i2c_reset associatedResetSinks ""
set_interface_property i2c_reset synchronousEdges DEASSERT
set_interface_property i2c_reset ENABLED true
set_interface_property i2c_reset EXPORT_OF ""
set_interface_property i2c_reset PORT_NAME_MAP ""
set_interface_property i2c_reset CMSIS_SVD_VARIABLES ""
set_interface_property i2c_reset SVD_ADDRESS_GROUP ""

add_interface_port i2c_reset i2c_reset reset Output 1

0 comments on commit f34ac31

Please sign in to comment.