axis_mii_tx: Add support for half duplex
This adds support for half-duplex. This is mostly done by predicating col and crs on half_duplex. In one place we need to go to IPG_LATE directly (although we could go to IPG_LATE like FCS with no loss of standard compliance). Signed-off-by: Sean Anderson <seanga2@gmail.com>
This commit is contained in:
parent
2fd6dedddb
commit
798968d3d6
|
@ -37,6 +37,8 @@ module axis_mii_tx (
|
||||||
|
|
||||||
/* Use a slot time of one octet for backoff; test purposes only */
|
/* Use a slot time of one octet for backoff; test purposes only */
|
||||||
input short_backoff,
|
input short_backoff,
|
||||||
|
/* Enable Half-Duplex */
|
||||||
|
input half_duplex,
|
||||||
|
|
||||||
/* Clause 4 TransmitStatus */
|
/* Clause 4 TransmitStatus */
|
||||||
output reg transmit_ok,
|
output reg transmit_ok,
|
||||||
|
@ -237,7 +239,7 @@ module axis_mii_tx (
|
||||||
replay_next = 0;
|
replay_next = 0;
|
||||||
done_next = 0;
|
done_next = 0;
|
||||||
retries_next = retries;
|
retries_next = retries;
|
||||||
collision_next = collision || mii_col;
|
collision_next = collision || (half_duplex && mii_col);
|
||||||
case (state)
|
case (state)
|
||||||
IPG_EARLY: begin
|
IPG_EARLY: begin
|
||||||
collision_next = 0;
|
collision_next = 0;
|
||||||
|
@ -262,7 +264,7 @@ module axis_mii_tx (
|
||||||
if (buf_valid) begin
|
if (buf_valid) begin
|
||||||
state_next = PREAMBLE;
|
state_next = PREAMBLE;
|
||||||
state_counter_next = PREAMBLE_BYTES - 1;
|
state_counter_next = PREAMBLE_BYTES - 1;
|
||||||
end else if (mii_crs) begin
|
end else if (half_duplex && mii_crs) begin
|
||||||
state_next = IPG_EARLY;
|
state_next = IPG_EARLY;
|
||||||
state_counter_next = IPG_EARLY_BYTES - 1;
|
state_counter_next = IPG_EARLY_BYTES - 1;
|
||||||
end
|
end
|
||||||
|
@ -472,8 +474,13 @@ module axis_mii_tx (
|
||||||
end
|
end
|
||||||
DRAIN: begin
|
DRAIN: begin
|
||||||
if (buf_ready && buf_valid && buf_last) begin
|
if (buf_ready && buf_valid && buf_last) begin
|
||||||
state_next = IPG_EARLY;
|
if (half_duplex) begin
|
||||||
state_counter_next = IPG_EARLY_BYTES - 1;
|
state_next = IPG_EARLY;
|
||||||
|
state_counter_next = IPG_EARLY_BYTES - 1;
|
||||||
|
end else begin
|
||||||
|
state_next = IPG_LATE;
|
||||||
|
state_counter_next = IPG_BYTES - 1;
|
||||||
|
end
|
||||||
end else begin
|
end else begin
|
||||||
buf_ready_next = 1;
|
buf_ready_next = 1;
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,6 +28,7 @@ async def init(mac):
|
||||||
mac.axis_valid.value = 0
|
mac.axis_valid.value = 0
|
||||||
mac.axis_err.value = 0
|
mac.axis_err.value = 0
|
||||||
mac.short_backoff.value = 1
|
mac.short_backoff.value = 1
|
||||||
|
mac.half_duplex.value = 1
|
||||||
await Timer(1)
|
await Timer(1)
|
||||||
mac.rst.value = 0
|
mac.rst.value = 0
|
||||||
await cocotb.start(Clock(mac.clk, 8, units='ns').start())
|
await cocotb.start(Clock(mac.clk, 8, units='ns').start())
|
||||||
|
@ -325,3 +326,20 @@ async def test_collision(mac):
|
||||||
await late(mac, packet, 64 * BYTE_TIME_NS)
|
await late(mac, packet, 64 * BYTE_TIME_NS)
|
||||||
await late(mac, packet, randtime(64, 256))
|
await late(mac, packet, randtime(64, 256))
|
||||||
await late(mac, packet, 72 * BYTE_TIME_NS - 1)
|
await late(mac, packet, 72 * BYTE_TIME_NS - 1)
|
||||||
|
|
||||||
|
@cocotb.test(timeout_time=10, timeout_unit='us')
|
||||||
|
async def test_full_duplex(mac):
|
||||||
|
await init(mac)
|
||||||
|
mac.half_duplex.value = 0
|
||||||
|
|
||||||
|
# Skip to the end of IPG_LATE
|
||||||
|
await Timer(13 * BYTE_TIME_NS, 'ns')
|
||||||
|
mac.mii_crs.value = 1
|
||||||
|
packet = list(range(32))
|
||||||
|
send, status = await start(mac, packet)
|
||||||
|
recv = await cocotb.start(ok(mac, packet, status, 16 * BYTE_TIME_NS))
|
||||||
|
# No deferral
|
||||||
|
await Timer(13 * BYTE_TIME_NS, 'ns')
|
||||||
|
assert mac.mii_tx_en.value
|
||||||
|
# No collision
|
||||||
|
await recv
|
||||||
|
|
Loading…
Reference in New Issue