A
audrey
Guest
Je suis en train de faire mon projet dans le gigabit ethernet 802.3z protocole.J'utilise verilog que ma langue (Xilinx) et je suis en train d'utiliser mon simulateur ModelSim.J'ai fait le code dans le module de formulaire de l'émetteur et le récepteur.Le principal objectif de notre projet est de transmettre l'image que par le format, puis de recevoir les données transmises lors de la sortie du récepteur.
Nous faisons de la Testbench pour le code que nous avons mis en place et nous sommes censés utiliser dat tâches afin que l'utilisateur peut entrer les données,
la source et l'adresse de destination et la longueur des données en octets.Nous avons également besoin de demander à l'utilisateur wat type de cadre, il veut transmettre et, par conséquent, la tâche d'appel.
S'il vous plaît, aidez-moi dans la mise en uvre des tâches que Thees Je trouve
qu'il est très difficile.J'ai besoin de votre aide urgente.En vous remerciant.
Ceci est mon code
module rx_mac (
rx_clk,
reset_n,
rx_dv,
rx_error,
rx_data,
données,
rx_status_valid_n,
rx_status,
data_valid,
last_data,
eth_address
);
rx_clk d'entrée,
reset_n,
rx_dv,
rx_error;
input [3:0] rx_data;
input [47:0] eth_address;
sortie rx_status_valid_n,
data_valid,
last_data;
sortie [3:0] data;
sortie [15:0] rx_status;
SFD_start_detect fil,
SFD_detected,
FCS_start_check,
data_en,
address_match,
multicast,
la diffusion,
crc_ok;
wire [3:0] data_tap,
des données;
rx_sm rx_sm (
. clk (rx_clk),
. reset_n (reset_n),
. rx_dv (rx_dv),
. rx_error (rx_error),
. SFD_detected (SFD_detected),
. address_match (address_match),
. multidiffusion (multicast),
. diffusion (broadcast),
. crc_ok (crc_ok),
. SFD_start_detect (SFD_start_detect),
. FCS_start_check (FCS_start_check),
. data_en (data_en),
. data_valid (data_valid),
. last_data (last_data),
. rx_status_valid_n (rx_status_valid_n),
. rx_status (rx_status)
);
rx_buffer rx_buffer (
. clk (rx_clk),
. reset_n (reset_n),
. rx_data (rx_data),
. data_tap (data_tap),
. data (données),
. data_en (data_en)
);
SFD_detector rx_sfd (
. clk (rx_clk),
. reset_n (reset_n),
. data_tap (data_tap),
. SFD_start_detect (SFD_start_detect),
. SFD_detected (SFD_detected)
);
aml rx_aml (
. clk (rx_clk),
. reset_n (reset_n),
. data_tap (data_tap),
. eth_address (eth_address),
. SFD_detected (SFD_detected),
. address_match (address_match),
. multidiffusion (multicast),
. broadcast (diffusion)
);
fcs_check rx_fcs (
. clk (rx_clk),
. reset_n (reset_n),
. FCS_start_check (FCS_start_check),
. data (données),
. crc_ok (crc_ok)
);
endmodule«définir INIT_COUNT (4'b0000)
«définir END_COUNT (4'b1100)
«définir DIFFUSION (48'hFFFFFFFFFFFF)
«définir ZERO_DA (48'h000000000000)
«définir MULTICAST_SIGN (48'h010000000000)
module aml (
clk,
reset_n,
data_tap,
eth_address,
SFD_detected,
address_match,
la diffusion,
multicast
);
input clk,
SFD_detected,
reset_n;
input [7:0] data_tap;
input [47:0] eth_address;
sortie address_match,
multicast,
diffusion;
reg address_match,
multicast,
la diffusion,
start_count;
reg [1:0] state_AML;
reg [3:0] AML_count;
reg [7:0] data_tap_temp;
reg [47:0] DA;
paramètre AML_IDLE = 2'b00,
AML_RUN = 2'b01,
AML_STOP = 2'b10;
toujours @ (posedge clk ou negedge reset_n)
if (! reset_n)
state_AML <= AML_IDLE;
autre
cas (state_AML)
AML_IDLE:
if (SFD_detected)
commencer
start_count <= 1'b1;
state_AML <= AML_RUN;
fin
autre
commencer
start_count <= 1'b0;
DA = `ZERO_DA;
state_AML <= AML_IDLE;
fin
AML_RUN:
if (AML_count == `END_COUNT)
state_AML <= AML_STOP;
autre
commencer
state_AML <= AML_RUN;
cas (AML_count)
4'b0000: DA [7:0] = data_tap_temp [7:0];
4'b0001: DA [15:8] = data_tap_temp [7:0];
4'b0010: DA [23:16] = data_tap_temp [7:0];
4'b0011: DA [31:24] = data_tap_temp [7:0];
4'b0100: DA [39:32] = data_tap_temp [7:0];
4'b0101: DA [47:40] = data_tap_temp [7:0];
par défaut:
DA = `ZERO_DA;
endcase
fin
AML_STOP:
commencer
start_count <= 1'b0;
state_AML <= AML_IDLE;
fin
endcase
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
commencer
address_match = 1'b0;
diffusion = 1'b0;
multicast = 1'b0;
fin
autre
if (state_AML == AML_IDLE)
commencer
address_match = 1'b0;
diffusion = 1'b0;
multicast = 1'b0;
fin
autre
cas (DA)
»DIFFUSION:
commencer
diffusion = 1'b1;
address_match = 1'b1;
fin
eth_address:
address_match = 1'b1;
(eth_address | `MULTICAST_SIGN):
commencer
multicast = 1'b1;
address_match = 1'b1;
fin
par défaut:
address_match = 1'b0;
endcase
fin
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
data_tap_temp <= 8'b00000000;
autre
data_tap_temp <= data_tap;
fin
toujours @ (posedge clk ou negedge reset_n)
if (! reset_n)
AML_count <= `INIT_COUNT;
autre
if (! start_count)
AML_count <= `INIT_COUNT;
autre
AML_count <= (AML_count 1'b1);
endmodule
«définir BUFFER_INIT_VALUE 32'hFFFFFFFF
«définir CRCO_RESET 9'b000000000
«définir CRC_NOT 9'b111111111
module fcs_check (
clk,
reset_n,
FCS_start_check,
données,
crc_ok
);
FCS_start_check entrée;
input [7:0] data;
input clk;
reset_n d'entrée;
crc_ok de sortie;
reg crc_ok;
reg [31:0] crc_buffer;
fonction [31:0] count_crc;
input [3:0] d;
input [31:0] c;
reg [3:0] d;
reg [31:0] c;
reg [31:0] new_crc;
commencer
new_crc [0] = d [3] ^ c [28];
new_crc [1] = d [2] ^ d [3] ^ c [28] ^ c [29];
new_crc [2] = d [1] ^ d [2] ^ d [3] ^ c [28] ^ c [29] ^ c [30];
new_crc [3] = d [0] ^ d [1] ^ d [2] ^ c [29] ^ c [30] ^ c [31];
new_crc [4] = d [0] ^ d [1] ^ d [3] ^ c [0] ^ c [28] ^ c [30] ^ c [31];
new_crc [5] = d [0] ^ d [2] ^ d [3] ^ c [1] ^ c [28] ^ c [29] ^ c [31];
new_crc [6] = d [1] ^ d [2] ^ c [2] ^ c [29] ^ c [30];
new_crc [7] = d [0] ^ d [1] ^ d [3] ^ c [3] ^ c [28] ^ c [30] ^ c [31];
new_crc [8] = d [0] ^ d [2] ^ d [3] ^ c [4] ^ c [28] ^ c [29] ^ c [31];
new_crc [9] = d [1] ^ d [2] ^ c [5] ^ c [29] ^ c [30];
new_crc [10] = d [0] ^ d [1] ^ d [3] ^ c [6] ^ c [28] ^ c [30] ^ c [31];
new_crc [11] = d [0] ^ d [2] ^ d [3] ^ c [7] ^ c [28] ^ c [29] ^ c [31];
new_crc [12] = d [1] ^ d [2] ^ d [3] ^ c [8] ^ c [28] ^ c [29] ^ c [30];
new_crc [13] = d [0] ^ d [1] ^ d [2] ^ c [9] ^ c [29] ^ c [30] ^ c [31];
new_crc [14] = d [0] ^ d [1] ^ c [10] ^ c [30] ^ c [31];
new_crc [15] = d [0] ^ c [11] ^ c [31];
new_crc [16] = d [3] ^ c [12] ^ c [28];
new_crc [17] = d [2] ^ c [13] ^ c [29];
new_crc [18] = d [1] ^ c [14] ^ c [30];
new_crc [19] = d [0] ^ c [15] ^ c [31];
new_crc [20] = c [16];
new_crc [21] = c [17];
new_crc [22] = d [3] ^ c [18] ^ c [28];
new_crc [23] = d [2] ^ d [3] ^ c [19] ^ c [28] ^ c [29];
new_crc [24] = d [1] ^ d [2] ^ c [20] ^ c [29] ^ c [30];
new_crc [25] = d [0] ^ d [1] ^ c [21] ^ c [30] ^ c [31];
new_crc [26] = d [0] ^ d [3] ^ c [22] ^ c [28] ^ c [31];
new_crc [27] = d [2] ^ c [23] ^ c [29];
new_crc [28] = d [1] ^ c [24] ^ c [30];
new_crc [29] = d [0] ^ c [25] ^ c [31];
new_crc [30] = c [26];
new_crc [31] = c [27];
count_crc = new_crc;
fin
endfunction
toujours @ (posedge clk)
commencer
if (crc_buffer == 32'hc704dd7b) / /: nombre magique
crc_ok <= 1'b1;
autre
crc_ok <= 1'b0;
fin
toujours @ (posedge clk)
commencer
if (! reset_n)
crc_buffer <= `BUFFER_INIT_VALUE;
autre
if (FCS_start_check)
crc_buffer <= count_crc (données, crc_buffer);
autre
crc_buffer <= `BUFFER_INIT_VALUE;
fin
endmodule
module rx_buffer (
clk,
reset_n,
rx_data,
data_tap,
données,
data_en
);
input clk, data_en, reset_n;
input [7:0] rx_data;
sortie [7:0] data_tap,
des données;
reg [7:0] data_tap;
reg [7:0] data_temp;
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
data_tap <= 8'b00000000;
autre
data_tap <= rx_data;
fin
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
data_temp <= 8'b00000000;
autre
data_temp <= data_tap;
fin
assign = data_en données?data_temp: 8'bzzzzzzzz;
endmodule«définir INITIAL_COUNT 12'b000000000000
«définir MAX_COUNT 12'b101111011100
«définir STATUS_RESET 16'b0000000000000000
«définir STATUS_ERROR 15'b000000000000000
«définir eo_DA 12'b000000001011
«définir GET_CRC_OUT 12'b000000001101
«définir CRCO_ZERO 9'b000000000
«définir Rx_IDLE 4'b000
«définir SFD_detect 4'b001
«définir Rx_RUN 4'b010
«définir Rx_HOLD 4'b011
«définir Rx_STOP 4'b100
«définir WRITE_STATUS 4'b101
«définir HOLD1_STATUS 4'b110
«définir HOLD2_STATUS 4'b111
module rx_sm (
clk,
reset_n,
rx_dv,
rx_error,
SFD_detected,
address_match,
multicast,
la diffusion,
crc_ok,
SFD_start_detect,
data_en,
FCS_start_check,
last_data,
data_valid,
rx_status_valid_n,
rx_status
);
input clk,
reset_n,
rx_dv,
rx_error,
SFD_detected,
address_match,
multicast,
la diffusion,
crc_ok;
sortie SFD_start_detect,
data_en,
FCS_start_check,
last_data,
data_valid,
rx_status_valid_n;
sortie [15:0] rx_status;
reg SFD_start_detect,
FCS_start_check,
data_en,
last_data,
broadcast_temp,
multicast_temp,
address_match_temp,
data_valid,
rx_error_temp,
sending_data_n_status,
rx_status_valid_n;
reg [3:0] rx_sm_state;
reg [12:0] nibble_count,
nibble_count_temp;
reg [15:0] rx_status;
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
rx_sm_state <= `Rx_IDLE;
autre
if (rx_error)
commencer
rx_error_temp <= 1'b1;
rx_sm_state <= `Rx_HOLD;
fin
autre
si ((nibble_count_temp 2'b10) == `MAX_COUNT)
commencer
rx_error_temp <= 1'b1;
rx_sm_state <= `Rx_HOLD;
fin
autre
cas (rx_sm_state)
»Rx_IDLE:
commencer
if (rx_dv)
commencer
rx_sm_state <= `SFD_detect;
SFD_start_detect <= 1'b1;
fin
autre
commencer
SFD_start_detect <= 1'b0;
data_en <= 1'b0;
FCS_start_check <= 1'b0;
rx_status_valid_n <= 1'b1;
rx_status <= `STATUS_RESET;
last_data <= 1'b0;
data_valid <= 1'b0;
sending_data_n_status <= 1'b0;
rx_sm_state <= `Rx_IDLE;
rx_error_temp <= 1'b0;
fin
fin
»SFD_detect:
commencer
if (! rx_dv)
rx_sm_state <= `Rx_HOLD;
autre
if (SFD_detected)
commencer
SFD_start_detect <= 1'b0;
FCS_start_check <= 1'b1;
data_valid <= 1'b1;
sending_data_n_status <= 1'b1;
data_en <= 1'b1;
rx_sm_state <= `Rx_RUN;
fin
autre
rx_sm_state <= `SFD_detect;
fin
»Rx_RUN:
commencer
if (! rx_dv)
commencer
last_data <= 1'b1;
rx_sm_state <= `Rx_HOLD;
fin
autre
rx_sm_state <= `Rx_RUN;
fin
»Rx_HOLD:
commencer
last_data <= 1'b0;
data_valid <= 1'b0;
data_en <= 1'b0;
rx_sm_state <= `Rx_STOP;
fin
»Rx_STOP:
commencer
FCS_start_check <= 1'b0;
rx_sm_state <= `WRITE_STATUS;
fin
»WRITE_STATUS:
commencer
rx_status_valid_n <= 1'b0;
rx_status [0] <= rx_error_temp;
rx_status [1] <= address_match_temp;
rx_status [2] <= (broadcast_temp | multicast_temp);
rx_status [3] <= crc_ok;
rx_status [15:4] <= nibble_count 1'b1;
rx_sm_state <= `HOLD1_STATUS;
fin
»HOLD1_STATUS:
commencer
rx_sm_state <= `HOLD2_STATUS;
fin
»HOLD2_STATUS:
rx_sm_state <= `Rx_IDLE;
par défaut:
rx_sm_state <= `Rx_IDLE;
endcase
fin
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
nibble_count_temp <= `INITIAL_COUNT;
autre
if (! data_en)
nibble_count_temp <= `INITIAL_COUNT;
autre
nibble_count_temp <= (nibble_count_temp 1'b1);
fin
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
nibble_count <= `INITIAL_COUNT;
autre
if (data_en)
nibble_count <= nibble_count_temp;
autre
nibble_count <= nibble_count;
fin
toujours @ (posedge clk)
commencer
if (! reset_n)
commencer
broadcast_temp <= 1'b0;
multicast_temp <= 1'b0;
address_match_temp <= 1'b0;
fin
autre
if (! sending_data_n_status)
commencer
broadcast_temp <= 1'b0;
multicast_temp <= 1'b0;
address_match_temp <= 1'b0;
fin
autre
if (address_match)
commencer
broadcast_temp <= émission;
multicast_temp <= multicast;
address_match_temp <= address_match;
fin
autre
commencer
broadcast_temp <= broadcast_temp;
multicast_temp <= multicast_temp;
address_match_temp <= address_match_temp;
fin
fin
endmodule
module SFD_detector (
clk,
reset_n,
data_tap,
SFD_start_detect,
SFD_detected
);
input clk, SFD_start_detect, reset_n;
input [3:0] data_tap;
SFD_detected de sortie;
reg SFD_detected;
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
SFD_detected <= 1'b0;
autre
if (! SFD_start_detect)
SFD_detected <= 1'b0;
autre
commencer
if (data_tap == 4'b1101)
SFD_detected <= 1'b1;
autre
SFD_detected <= 1'b0;
fin
fin
endmodulemodule txethmac (
tx_data,
tx_sof,
tx_eof,
tx_underrun,
full_duplex,
reset_n,
crs,
coll,
tx_clk,
tx_data_used,
tx_done,
tx_abort,
tx_retransmit,
tx_status,
tx_status_valid_n,
TxD,
tx_en,
tx_er
);
/ / Du DMA
input [7:0] tx_data;
tx_sof d'entrée;
tx_eof d'entrée;
tx_underrun d'entrée;
full_duplex d'entrée;
reset_n d'entrée;
/ / De MII
crs entrée;
entrée coll;
tx_clk d'entrée;
/ / Pour MII
sortie [7:0] TXD;
tx_en de sortie;
tx_er de sortie;
/ / Pour DMA
tx_data_used de sortie;
tx_done de sortie;
tx_abort de sortie;
tx_retransmit de sortie;
sortie [6:0] tx_status;
tx_status_valid_n de sortie;
wire [7:0] data;
transmit_error fil;
transmit_enable fil;
compute_crc fil;
wire [7:0] crc;
wire [2:0] data_select;
transmit_available_p fil;
transmit_new_p fil;
excess_deferral fil;
transmit_preamble fil;
transmit_sfd fil;
wire [3:0] coll_attempt;
late_coll fil;
excessive_coll fil;
coll_event_p fil;
transmit_64byte fil;
transmit_fcs fil;
wire [11:0] count_length;
wire [3:0] count_fcs;
excessive_length fil;
wire [3:0] count_jam;
wire [9:0] hasard;
backoff_p fil;
start_backoff fil;
/ / instancie modules
fifo_synch tx_1 (
. data (données),
. transmit_enable (transmit_enable),
. transmit_error (transmit_error),
. clk (tx_clk),
. TXD (TXD),
. tx_en (tx_en),
. tx_er (tx_er)
);
ifg_timer tx_2 (
. crs (crs),
. full_duplex (full_duplex),
. transmit_enable (transmit_enable),
. clk (tx_clk),
. reset_n (reset_n),
. transmit_available_p (transmit_available_p)
);
defer_counter tx_3 (
. transmit_available_p (transmit_available_p),
. transmit_new_p (transmit_new_p),
. clk (tx_clk),
. reset_n (reset_n),
. excess_deferral (excess_deferral)
);
frame_length_counter tx_4 (
. transmit_enable (transmit_enable),
. transmit_fcs (transmit_fcs),
. clk (tx_clk),
. reset_n (reset_n),
. count_length (count_length),
. count_fcs (count_fcs),
. excessive_length (excessive_length),
. transmit_64byte (transmit_64byte)
);
/ / coll_counter tx_5 (
/ /. transmit_new_p (transmit_new_p),
/ /. transmit_enable (transmit_enable),
/ /. Transmit_preamble (transmit_preamble),
/ /. Transmit_sfd (transmit_sfd),
/ /. Transmit_64byte (transmit_64byte),
/ /. Clk (tx_clk),
/ /. Reset_n (reset_n),
/ /. Coll (coll),
/ /. Full_duplex (full_duplex),
/ /. Coll_event_p (coll_event_p),
/ /. Late_coll (late_coll),
/ /. Excessive_coll (excessive_coll),
/ /. Coll_attempt (coll_attempt)
/ /);
/ / random_number_gen tx_6 (
/ /. Coll_attempt (coll_attempt),
/ /. Clk (tx_clk),
/ /. Reset_n (reset_n),
/ /. Aléatoire (random)
/ /);
/ / backoff_timer tx_7 (
/ /. start_backoff (start_backoff),
/ /. aléatoire (random),
/ /. clk (tx_clk),
/ /. reset_n (reset_n),
/ /. backoff_p (backoff_p)
/ /);
/ / jam_timer tx_8 (
/ /. coll_event_p (coll_event_p),
/ /. clk (tx_clk),
/ /. reset_n (reset_n),
/ /. count_jam (count_jam)
/ /);
crc_gen tx_9 (
. compute_crc (compute_crc),
. data (données),
. clk (tx_clk),
. reset_n (reset_n),
. crc (crc)
);
data_mux tx_10 (
. data_select (data_select),
. data_in (tx_data),
. crc (CRC),
. data_out (données)
);
tx_state_machine tx_11 (
. tx_sof (tx_sof),
. tx_eof (tx_eof),
. tx_underrun (tx_underrun),
. clk (tx_clk),
. reset_n (reset_n),
. transmit_available_p (transmit_available_p),
. excess_deferral (excess_deferral),
. coll_event_p (coll_event_p),
. late_coll (late_coll),
. excessive_coll (excessive_coll),
. backoff_p (backoff_p),
. count_length (count_length),
. count_fcs (count_fcs),
. excessive_length (excessive_length),
. count_jam (count_jam),
. tx_data_used (tx_data_used),
. tx_done (tx_done),
. tx_abort (tx_abort),
. tx_retransmit (tx_retransmit),
. tx_status (tx_status),
. tx_status_valid_n (tx_status_valid_n),
. transmit_new_p (transmit_new_p),
. transmit_enable (transmit_enable),
. transmit_preamble (transmit_preamble),
. transmit_sfd (transmit_sfd),
. transmit_fcs (transmit_fcs),
. transmit_error (transmit_error),
. start_backoff (start_backoff),
. compute_crc (compute_crc),
. data_select (data_select)
);«définir CRC_INIT_VALUE (32'hFFFF_FFFF)
«définir CRC_IDLE (2'b00)
«définir CRC_RUN (2'b01)
«définir CRC_STOP (2'b11)
module crc_gen (
compute_crc,
données,
clk,
reset_n,
crc
);
compute_crc d'entrée;
input [7:0] data;
input clk;
reset_n d'entrée;
sortie [7:0] crc;
reg [1:0] state_crc;
reg [31:0] crc_buffer;
reg [2:0] crc_end;
fonction [31:0] count_crc, / /, la première série de données est peu d [0]
input [3:0] d;
input [31:0] c;
reg [31:0] new_crc;
commencer
new_crc [0] = d [3] ^ c [28];
new_crc [1] = d [2] ^ d [3] ^ c [28] ^ c [29];
new_crc [2] = d [1] ^ d [2] ^ d [3] ^ c [28] ^ c [29] ^ c [30];
new_crc [3] = d [0] ^ d [1] ^ d [2] ^ c [29] ^ c [30] ^ c [31];
new_crc [4] = d [0] ^ d [1] ^ d [3] ^ c [0] ^ c [28] ^ c [30] ^ c [31];
new_crc [5] = d [0] ^ d [2] ^ d [3] ^ c [1] ^ c [28] ^ c [29] ^ c [31];
new_crc [6] = d [1] ^ d [2] ^ c [2] ^ c [29] ^ c [30];
new_crc [7] = d [0] ^ d [1] ^ d [3] ^ c [3] ^ c [28] ^ c [30] ^ c [31];
new_crc [8] = d [0] ^ d [2] ^ d [3] ^ c [4] ^ c [28] ^ c [29] ^ c [31];
new_crc [9] = d [1] ^ d [2] ^ c [5] ^ c [29] ^ c [30];
new_crc [10] = d [0] ^ d [1] ^ d [3] ^ c [6] ^ c [28] ^ c [30] ^ c [31];
new_crc [11] = d [0] ^ d [2] ^ d [3] ^ c [7] ^ c [28] ^ c [29] ^ c [31];
new_crc [12] = d [1] ^ d [2] ^ d [3] ^ c [8] ^ c [28] ^ c [29] ^ c [30];
new_crc [13] = d [0] ^ d [1] ^ d [2] ^ c [9] ^ c [29] ^ c [30] ^ c [31];
new_crc [14] = d [0] ^ d [1] ^ c [10] ^ c [30] ^ c [31];
new_crc [15] = d [0] ^ c [11] ^ c [31];
new_crc [16] = d [3] ^ c [12] ^ c [28];
new_crc [17] = d [2] ^ c [13] ^ c [29];
new_crc [18] = d [1] ^ c [14] ^ c [30];
new_crc [19] = d [0] ^ c [15] ^ c [31];
new_crc [20] = c [16];
new_crc [21] = c [17];
new_crc [22] = d [3] ^ c [18] ^ c [28];
new_crc [23] = d [2] ^ d [3] ^ c [19] ^ c [28] ^ c [29];
new_crc [24] = d [1] ^ d [2] ^ c [20] ^ c [29] ^ c [30];
new_crc [25] = d [0] ^ d [1] ^ c [21] ^ c [30] ^ c [31];
new_crc [26] = d [0] ^ d [3] ^ c [22] ^ c [28] ^ c [31];
new_crc [27] = d [2] ^ c [23] ^ c [29];
new_crc [28] = d [1] ^ c [24] ^ c [30];
new_crc [29] = d [0] ^ c [25] ^ c [31];
new_crc [30] = c [26];
new_crc [31] = c [27];
count_crc = new_crc;
fin
endfunction
attribuer crc [7] = ~ crc_buffer [24];
attribuer crc [6] = ~ crc_buffer [25];
attribuer crc [5] = ~ crc_buffer [26];
crc céder [4] = ~ crc_buffer [27];
attribuer crc [3] = ~ crc_buffer [28];
attribuer crc [2] = ~ crc_buffer [29];
attribuer crc [1] = ~ crc_buffer [30];
attribuer crc [0] = ~ crc_buffer [31];
toujours @ (posedge clk ou negedge reset_n)
if (! reset_n)
state_crc <= `CRC_IDLE;
autre
cas (state_crc)
»CRC_IDLE:
if (compute_crc)
commencer
state_crc <= `CRC_RUN;
crc_buffer <= count_crc (données, CRC_INIT_VALUE »);
fin
autre
commencer
state_crc <= `CRC_IDLE;
crc_buffer <= 32'h0000_0000;
crc_end <= 3'd0;
fin
»CRC_RUN:
if (! Compute_crc)
commencer
state_crc <= `CRC_STOP;
crc_buffer <= crc_buffer <<8;
fin
autre
commencer
state_crc <= `CRC_RUN;
crc_buffer <= count_crc (données, crc_buffer);
fin
»CRC_STOP:
if (crc_end == 3'110)
commencer
state_crc <= `CRC_IDLE;
crc_buffer <= 32'h0000_0000;
fin
autre
commencer
state_crc <= `CRC_STOP;
crc_buffer <= crc_buffer <<4;
crc_end <= crc_end 1'b1;
fin
endcase
endmodule
«définir PATTERN_PREAMBLE (8'b01010101)
«définir PATTERN_SFD (8'b11010101)
module data_mux (
data_select,
data_in,
crc,
data_out,
count_length
);
input [2:0] data_select;
input [7:0] data_in;
input [7:0] crc;
input [7:0] count_length;
sortie [7:0] data_out;
reg [7:0] data_out;
toujours @ (data_select ou data_in ou crc)
cas (data_select)
3'b000: data_out = data_in;
3'b001: data_out = `PATTERN_PREAMBLE;
3'b010: data_out = `PATTERN_SFD;
3'b011: data_out = crc;
3'b100: data_out = src_add;
3'b101: data_out = dst_add;
3'b110: data_out = count_length;
par défaut: data_out = 8'h00;
endcase
endmodule
module fifo_synch (
données,
transmit_enable,
transmit_error,
clk,
TxD,
tx_en,
tx_er
);
input [7:0] data;
transmit_enable d'entrée;
transmit_error d'entrée;
input clk;
sortie [7:0] TXD;
tx_en de sortie;
tx_er de sortie;
reg [7:0] TXD;
reg tx_en;
reg tx_er;
toujours @ (posedge clk)
if (transmit_enable)
commencer
TXD <= data;
tx_en <= 1'b1;
tx_er <= transmit_error;
fin
autre
commencer
TXD <= 8'h00;
tx_en <= 1'b0;
tx_er <= 1'b0;
fin
endmodule«définir COUNT_LENGTH_IDLE (2'b00)
«définir COUNT_LENGTH_RUN (2'b01)
«définir COUNT_LENGTH_FCS (2'b11)
«définir MIN_LENGTH (12'd144)
«définir max_length (12'd3052)
module frame_length_counter (
transmit_enable,
transmit_fcs,
clk,
reset_n,
count_length,
count_fcs,
excessive_length,
transmit_64byte
);
transmit_enable d'entrée;
transmit_fcs d'entrée;
input clk;
reset_n d'entrée;
sortie [11:0] count_length;
sortie [3:0] count_fcs;
excessive_length de sortie;
transmit_64byte de sortie;
reg [11:0] count_length;
reg [3:0] count_fcs;
reg excessive_length;
reg transmit_64byte;
reg [1:0] state_length;
fonction [11:0] inc_length;
input [11:0] count_length;
commencer
inc_length = count_length 1'b1;
fin
endfunction
toujours @ (posedge clk ou negedge reset_n)
if (! reset_n)
commencer
state_length <= `COUNT_LENGTH_IDLE;
count_length <= 12'd0;
count_fcs <= 4'd0;
fin
autre
cas (state_length)
»COUNT_LENGTH_IDLE:
if (transmit_enable)
commencer
state_length <= `COUNT_LENGTH_RUN;
count_length <= 12'd1;
fin
autre
state_length <= `COUNT_LENGTH_IDLE;
»COUNT_LENGTH_RUN:
if (! Transmit_enable)
state_length <= `COUNT_LENGTH_IDLE;
autre
if (transmit_fcs)
commencer
state_length <= `COUNT_LENGTH_FCS;
count_length <= inc_length (count_length);
count_fcs <= 4'd1;
fin
autre
commencer
state_length <= `COUNT_LENGTH_RUN;
count_length <= inc_length (count_length);
fin
»COUNT_LENGTH_FCS:
if (! Transmit_enable)
state_length <= `COUNT_LENGTH_IDLE;
autre
commencer
state_length <= `COUNT_LENGTH_FCS;
count_length <= inc_length (count_length);
count_fcs <= (count_fcs 1'b1);
fin
endcase
toujours @ (count_length)
commencer
transmit_64byte = (count_length> »MIN_LENGTH-1)?1'b1: 1'b0;
excessive_length = (count_length> »max_length-1)?1'b1: 1'b0;
fin
endmodule«définir IFG_LENGTH_1 (5'd15)
«définir IFG_LENGTH_2 (5'd22)
«définir IFG_IDLE (1'b0)
«définir IFG_RUN (1'b1)
module ifg_timer (
crs,
full_duplex,
transmit_enable,
clk,
reset_n,
transmit_available_p
);
crs entrée;
full_duplex d'entrée;
transmit_enable d'entrée;
input clk;
reset_n d'entrée;
transmit_available_p de sortie;
reg transmit_available_p;
reg [4:0] count_ifg;
reg state_ifg;
Fonction [4:0] inc_ifg;
input [4:0] count_ifg;
commencer
inc_ifg = count_ifg 1'b1;
fin
endfunction
toujours @ (posedge clk ou negedge reset_n)
if (! reset_n)
state_ifg <= `IFG_IDLE;
autre
if (full_duplex)
cas (state_ifg)
»IFG_IDLE:
if (! Transmit_enable)
commencer
state_ifg <= `IFG_RUN;
count_ifg <= 5'd1;
transmit_available_p <= 1'b0;
fin
autre
commencer
state_ifg <= `IFG_IDLE;
count_ifg <= 5'd0;
transmit_available_p <= 1'b0;
fin
»IFG_RUN:
if (transmit_enable)
state_ifg <= `IFG_IDLE;
autre
if (count_ifg == `IFG_LENGTH_2-1)
commencer
state_ifg <= `IFG_IDLE;
transmit_available_p <= 1'b1;
fin
autre
commencer
state_ifg <= `IFG_RUN;
count_ifg <= inc_ifg (count_ifg);
fin
endcase
autre
cas (state_ifg)
»IFG_IDLE:
if (! Crs)
commencer
state_ifg <= `IFG_RUN;
count_ifg <= 5'd1;
transmit_available_p <= 1'b0;
fin
autre
commencer
state_ifg <= `IFG_IDLE;
count_ifg <= 5'd0;
transmit_available_p <= 1'b0;
fin
»IFG_RUN:
if (crs & & (count_ifg <=` IFG_LENGTH_1-1))
state_ifg <= `IFG_IDLE;
autre
if (count_ifg == `IFG_LENGTH_2-1)
commencer
state_ifg <= `IFG_IDLE;
transmit_available_p <= 1'b1;
fin
autre
commencer
state_ifg <= `IFG_RUN;
count_ifg <= inc_ifg (count_ifg);
fin
endcase
endmodule
«définir TRANSMIT_IDLE (4'b0000)
«définir NEW_TRANSMIT (4'b0001)
«définir WAIT_TRANSMIT (4'b0011)
«définir TRANSMIT_PREAMBLE (4'b0010)
«définir TRANSMIT_SFD (4'b0110)
«définir TRANSMIT_DATA (4'b0111)
«définir TRANSMIT_PAD (4'b0101)
«définir TRANSMIT_FCS (4'b0100)
«définir WAIT_DONE (4'b1100)
«définir TRANSMIT_DONE (4'b1101)
«définir TRANSMIT_JAM (4'b1111)
«définir WAIT_BACKOFF (4'b1110)
«définir WAIT_ABORT (4'b1010)
«définir TRANSMIT_ABORT (4'b1011)
«définir WRITE_STATUS (4'b1001)
/ / `define (4'b1000)
«définir PREAMBLE_LENGTH (12'd15)
«définir SFD_LENGTH (12'd1)
«définir DATA_LENGTH (12'd120)
«définir FCS_LENGTH (4'd
<img src="http://www.edaboard.com/images/smiles/icon_cool.gif" alt="Cool" border="0" />«définir JAM_LENGTH (4'd
<img src="http://www.edaboard.com/images/smiles/icon_cool.gif" alt="Cool" border="0" />«définir WIDTH_STATUS 7
module tx_state_machine (
tx_sof,
tx_eof,
tx_underrun,
clk,
reset_n,
transmit_available_p,
excess_deferral,
coll_event_p,
late_coll,
excessive_coll,
backoff_p,
count_length,
count_fcs,
excessive_length,
count_jam,
tx_data_used,
tx_done,
tx_abort,
tx_retransmit,
tx_status,
tx_status_valid_n,
transmit_new_p,
transmit_enable,
transmit_preamble,
transmit_sfd,
transmit_fcs,
transmit_error,
start_backoff,
compute_crc,
data_select
);
tx_sof d'entrée;
tx_eof d'entrée;
tx_underrun d'entrée;
input clk;
reset_n d'entrée;
transmit_available_p d'entrée;
excess_deferral d'entrée;
excessive_length d'entrée;
excessive_coll d'entrée;
late_coll d'entrée;
coll_event_p d'entrée;
backoff_p d'entrée;
input [11:0] count_length;
input [3:0] count_fcs;
input [3:0] count_jam;
tx_data_used de sortie;
tx_done de sortie;
tx_abort de sortie;
tx_retransmit de sortie;
sortie [ `WIDTH_STATUS-1: 0] tx_status;
tx_status_valid_n de sortie;
transmit_new_p de sortie;
transmit_enable de sortie;
transmit_preamble de sortie;
transmit_sfd de sortie;
transmit_fcs de sortie;
transmit_error de sortie;
start_backoff de sortie;
compute_crc de sortie;
sortie [2:0] data_select;
reg tx_data_used;
reg tx_done;
reg tx_abort;
reg tx_retransmit;
/ / Reg [ `WIDTH_STATUS-1: 0] tx_status;
reg tx_status_valid_n;
reg transmit_new_p;
reg transmit_enable;
reg transmit_preamble;
reg transmit_sfd;
reg transmit_fcs;
reg transmit_error;
reg start_backoff;
reg compute_crc;
reg [2:0] data_select;
reg [3:0] current_tx_state;
reg [3:0] next_tx_state;
toujours @ (posedge clk ou negedge reset_n)
if (! reset_n)
current_tx_state <= `TRANSMIT_IDLE;
autre
current_tx_state <= next_tx_state;
toujours @ (current_tx_state ou tx_sof ou tx_eof ou tx_underrun ou
transmit_available_p ou excess_deferral ou excessive_length ou
excessive_coll ou late_coll ou coll_event_p ou backoff_p ou
count_length ou count_fcs ou count_jam)
cas (current_tx_state)
»TRANSMIT_IDLE:
if (tx_sof)
next_tx_state = `NEW_TRANSMIT;
autre
next_tx_state = `TRANSMIT_IDLE;
»NEW_TRANSMIT:
if (! Tx_sof)
next_tx_state = `TRANSMIT_IDLE;
autre
next_tx_state = `WAIT_TRANSMIT;
»WAIT_TRANSMIT:
if (! Tx_sof)
next_tx_state = `TRANSMIT_IDLE;
autre
if (excess_deferral)
next_tx_state = `WAIT_ABORT;
autre
if (transmit_available_p)
next_tx_state = `TRANSMIT_PREAMBLE;
autre
next_tx_state = `WAIT_TRANSMIT;
»TRANSMIT_PREAMBLE:
if (! Tx_sof)
next_tx_state = `TRANSMIT_IDLE;
autre
if (count_length == `PREAMBLE_LENGTH-1)
next_tx_state = `TRANSMIT_SFD;
autre
next_tx_state = `TRANSMIT_PREAMBLE;
»TRANSMIT_SFD:
if (! Tx_sof)
next_tx_state = `TRANSMIT_IDLE;
autre
next_tx_state = `TRANSMIT_DATA;
»TRANSMIT_DATA:
if (coll_event_p)
next_tx_state = `TRANSMIT_JAM;
autre
if (tx_underrun | | excessive_length)
next_tx_state = `WAIT_ABORT;
autre
if (tx_eof)
commencer
if (count_length <(PREAMBLE_LENGTH ` ` SFD_LENGTH `DATA_LENGTH-1))
next_tx_state = `TRANSMIT_PAD;
autre
next_tx_state = `TRANSMIT_FCS;
fin
autre
next_tx_state = `TRANSMIT_DATA;
»TRANSMIT_PAD:
if (coll_event_p)
next_tx_state = `TRANSMIT_JAM;
autre
if (count_length == (PREAMBLE_LENGTH ` ` SFD_LENGTH `DATA_LENGTH-1))
next_tx_state = `TRANSMIT_FCS;
autre
next_tx_state = `TRANSMIT_PAD;
»TRANSMIT_FCS:
if (coll_event_p)
next_tx_state = `TRANSMIT_JAM;
autre
if (excessive_length)
next_tx_state = `WAIT_ABORT;
autre
if (count_fcs == `FCS_LENGTH-1)
next_tx_state = `WAIT_DONE;
autre
next_tx_state = `TRANSMIT_FCS;
»TRANSMIT_JAM:
if (count_jam ==` JAM_LENGTH-3)
commencer
if (late_coll | | excessive_coll)
next_tx_state = `WAIT_ABORT;
autre
next_tx_state = `WAIT_BACKOFF;
fin
autre
next_tx_state = `TRANSMIT_JAM;
»WAIT_BACKOFF:
if (backoff_p)
next_tx_state = `WAIT_TRANSMIT;
autre
next_tx_state = `WAIT_BACKOFF;
»WAIT_DONE:
if (coll_event_p)
next_tx_state = `TRANSMIT_JAM;
autre
if (excessive_length)
next_tx_state = `WAIT_ABORT;
autre
next_tx_state = `TRANSMIT_DONE;
»TRANSMIT_DONE: next_tx_state =` WRITE_STATUS;
»WAIT_ABORT: next_tx_state =` TRANSMIT_ABORT;
»TRANSMIT_ABORT: next_tx_state =` WRITE_STATUS;
»WRITE_STATUS: next_tx_state =` TRANSMIT_IDLE;
par défaut: next_tx_state = `TRANSMIT_IDLE;
endcase
toujours @ (current_tx_state)
cas (current_tx_state)
»TRANSMIT_IDLE:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»NEW_TRANSMIT:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b1;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»WAIT_TRANSMIT:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_PREAMBLE:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b1;
transmit_preamble = 1'b1;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b001;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_SFD:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b1;
transmit_preamble = 1'b0;
transmit_sfd = 1'b1;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b010;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_DATA:
commencer
tx_data_used = 1'b1;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b1;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b1;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_PAD:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b1;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b001;
compute_crc = 1'b1;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_FCS:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b1;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b1;
start_backoff = 1'b0;
data_select = 3'b011;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»WAIT_DONE:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_DONE:
commencer
tx_data_used = 1'b0;
tx_done = 1'b1;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_JAM:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b1;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b001;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»WAIT_BACKOFF:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b1;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b1;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»WAIT_ABORT:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_ABORT:
commencer
tx_data_used = 1'b0;tx_done = 1'b0;
tx_abort = 1'b1;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
end
`WRITE_STATUS :
begin
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b0;
end
default :
begin
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
end
endcase
assign tx_status [0] = excess_deferral;
assign tx_status [1] = late_coll;
assign tx_status [2] = excessive_coll;
assign tx_status [3] = 1'b0;
assign tx_status [4] = excessive_length;
assign tx_status [5] = (excess_deferral | late_coll | excessive_coll |
tx_underrun | excessive_length);
assign tx_status [6] = ~(excess_deferral | late_coll | excessive_coll |
tx_underrun | excessive_length);
always @(posedge clk)
if (tx_underrun)
transmit_error <= 1'b1; autretransmit_error <= 1'b0;
endmodule
Nous faisons de la Testbench pour le code que nous avons mis en place et nous sommes censés utiliser dat tâches afin que l'utilisateur peut entrer les données,
la source et l'adresse de destination et la longueur des données en octets.Nous avons également besoin de demander à l'utilisateur wat type de cadre, il veut transmettre et, par conséquent, la tâche d'appel.
S'il vous plaît, aidez-moi dans la mise en uvre des tâches que Thees Je trouve
qu'il est très difficile.J'ai besoin de votre aide urgente.En vous remerciant.
Ceci est mon code
module rx_mac (
rx_clk,
reset_n,
rx_dv,
rx_error,
rx_data,
données,
rx_status_valid_n,
rx_status,
data_valid,
last_data,
eth_address
);
rx_clk d'entrée,
reset_n,
rx_dv,
rx_error;
input [3:0] rx_data;
input [47:0] eth_address;
sortie rx_status_valid_n,
data_valid,
last_data;
sortie [3:0] data;
sortie [15:0] rx_status;
SFD_start_detect fil,
SFD_detected,
FCS_start_check,
data_en,
address_match,
multicast,
la diffusion,
crc_ok;
wire [3:0] data_tap,
des données;
rx_sm rx_sm (
. clk (rx_clk),
. reset_n (reset_n),
. rx_dv (rx_dv),
. rx_error (rx_error),
. SFD_detected (SFD_detected),
. address_match (address_match),
. multidiffusion (multicast),
. diffusion (broadcast),
. crc_ok (crc_ok),
. SFD_start_detect (SFD_start_detect),
. FCS_start_check (FCS_start_check),
. data_en (data_en),
. data_valid (data_valid),
. last_data (last_data),
. rx_status_valid_n (rx_status_valid_n),
. rx_status (rx_status)
);
rx_buffer rx_buffer (
. clk (rx_clk),
. reset_n (reset_n),
. rx_data (rx_data),
. data_tap (data_tap),
. data (données),
. data_en (data_en)
);
SFD_detector rx_sfd (
. clk (rx_clk),
. reset_n (reset_n),
. data_tap (data_tap),
. SFD_start_detect (SFD_start_detect),
. SFD_detected (SFD_detected)
);
aml rx_aml (
. clk (rx_clk),
. reset_n (reset_n),
. data_tap (data_tap),
. eth_address (eth_address),
. SFD_detected (SFD_detected),
. address_match (address_match),
. multidiffusion (multicast),
. broadcast (diffusion)
);
fcs_check rx_fcs (
. clk (rx_clk),
. reset_n (reset_n),
. FCS_start_check (FCS_start_check),
. data (données),
. crc_ok (crc_ok)
);
endmodule«définir INIT_COUNT (4'b0000)
«définir END_COUNT (4'b1100)
«définir DIFFUSION (48'hFFFFFFFFFFFF)
«définir ZERO_DA (48'h000000000000)
«définir MULTICAST_SIGN (48'h010000000000)
module aml (
clk,
reset_n,
data_tap,
eth_address,
SFD_detected,
address_match,
la diffusion,
multicast
);
input clk,
SFD_detected,
reset_n;
input [7:0] data_tap;
input [47:0] eth_address;
sortie address_match,
multicast,
diffusion;
reg address_match,
multicast,
la diffusion,
start_count;
reg [1:0] state_AML;
reg [3:0] AML_count;
reg [7:0] data_tap_temp;
reg [47:0] DA;
paramètre AML_IDLE = 2'b00,
AML_RUN = 2'b01,
AML_STOP = 2'b10;
toujours @ (posedge clk ou negedge reset_n)
if (! reset_n)
state_AML <= AML_IDLE;
autre
cas (state_AML)
AML_IDLE:
if (SFD_detected)
commencer
start_count <= 1'b1;
state_AML <= AML_RUN;
fin
autre
commencer
start_count <= 1'b0;
DA = `ZERO_DA;
state_AML <= AML_IDLE;
fin
AML_RUN:
if (AML_count == `END_COUNT)
state_AML <= AML_STOP;
autre
commencer
state_AML <= AML_RUN;
cas (AML_count)
4'b0000: DA [7:0] = data_tap_temp [7:0];
4'b0001: DA [15:8] = data_tap_temp [7:0];
4'b0010: DA [23:16] = data_tap_temp [7:0];
4'b0011: DA [31:24] = data_tap_temp [7:0];
4'b0100: DA [39:32] = data_tap_temp [7:0];
4'b0101: DA [47:40] = data_tap_temp [7:0];
par défaut:
DA = `ZERO_DA;
endcase
fin
AML_STOP:
commencer
start_count <= 1'b0;
state_AML <= AML_IDLE;
fin
endcase
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
commencer
address_match = 1'b0;
diffusion = 1'b0;
multicast = 1'b0;
fin
autre
if (state_AML == AML_IDLE)
commencer
address_match = 1'b0;
diffusion = 1'b0;
multicast = 1'b0;
fin
autre
cas (DA)
»DIFFUSION:
commencer
diffusion = 1'b1;
address_match = 1'b1;
fin
eth_address:
address_match = 1'b1;
(eth_address | `MULTICAST_SIGN):
commencer
multicast = 1'b1;
address_match = 1'b1;
fin
par défaut:
address_match = 1'b0;
endcase
fin
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
data_tap_temp <= 8'b00000000;
autre
data_tap_temp <= data_tap;
fin
toujours @ (posedge clk ou negedge reset_n)
if (! reset_n)
AML_count <= `INIT_COUNT;
autre
if (! start_count)
AML_count <= `INIT_COUNT;
autre
AML_count <= (AML_count 1'b1);
endmodule
«définir BUFFER_INIT_VALUE 32'hFFFFFFFF
«définir CRCO_RESET 9'b000000000
«définir CRC_NOT 9'b111111111
module fcs_check (
clk,
reset_n,
FCS_start_check,
données,
crc_ok
);
FCS_start_check entrée;
input [7:0] data;
input clk;
reset_n d'entrée;
crc_ok de sortie;
reg crc_ok;
reg [31:0] crc_buffer;
fonction [31:0] count_crc;
input [3:0] d;
input [31:0] c;
reg [3:0] d;
reg [31:0] c;
reg [31:0] new_crc;
commencer
new_crc [0] = d [3] ^ c [28];
new_crc [1] = d [2] ^ d [3] ^ c [28] ^ c [29];
new_crc [2] = d [1] ^ d [2] ^ d [3] ^ c [28] ^ c [29] ^ c [30];
new_crc [3] = d [0] ^ d [1] ^ d [2] ^ c [29] ^ c [30] ^ c [31];
new_crc [4] = d [0] ^ d [1] ^ d [3] ^ c [0] ^ c [28] ^ c [30] ^ c [31];
new_crc [5] = d [0] ^ d [2] ^ d [3] ^ c [1] ^ c [28] ^ c [29] ^ c [31];
new_crc [6] = d [1] ^ d [2] ^ c [2] ^ c [29] ^ c [30];
new_crc [7] = d [0] ^ d [1] ^ d [3] ^ c [3] ^ c [28] ^ c [30] ^ c [31];
new_crc [8] = d [0] ^ d [2] ^ d [3] ^ c [4] ^ c [28] ^ c [29] ^ c [31];
new_crc [9] = d [1] ^ d [2] ^ c [5] ^ c [29] ^ c [30];
new_crc [10] = d [0] ^ d [1] ^ d [3] ^ c [6] ^ c [28] ^ c [30] ^ c [31];
new_crc [11] = d [0] ^ d [2] ^ d [3] ^ c [7] ^ c [28] ^ c [29] ^ c [31];
new_crc [12] = d [1] ^ d [2] ^ d [3] ^ c [8] ^ c [28] ^ c [29] ^ c [30];
new_crc [13] = d [0] ^ d [1] ^ d [2] ^ c [9] ^ c [29] ^ c [30] ^ c [31];
new_crc [14] = d [0] ^ d [1] ^ c [10] ^ c [30] ^ c [31];
new_crc [15] = d [0] ^ c [11] ^ c [31];
new_crc [16] = d [3] ^ c [12] ^ c [28];
new_crc [17] = d [2] ^ c [13] ^ c [29];
new_crc [18] = d [1] ^ c [14] ^ c [30];
new_crc [19] = d [0] ^ c [15] ^ c [31];
new_crc [20] = c [16];
new_crc [21] = c [17];
new_crc [22] = d [3] ^ c [18] ^ c [28];
new_crc [23] = d [2] ^ d [3] ^ c [19] ^ c [28] ^ c [29];
new_crc [24] = d [1] ^ d [2] ^ c [20] ^ c [29] ^ c [30];
new_crc [25] = d [0] ^ d [1] ^ c [21] ^ c [30] ^ c [31];
new_crc [26] = d [0] ^ d [3] ^ c [22] ^ c [28] ^ c [31];
new_crc [27] = d [2] ^ c [23] ^ c [29];
new_crc [28] = d [1] ^ c [24] ^ c [30];
new_crc [29] = d [0] ^ c [25] ^ c [31];
new_crc [30] = c [26];
new_crc [31] = c [27];
count_crc = new_crc;
fin
endfunction
toujours @ (posedge clk)
commencer
if (crc_buffer == 32'hc704dd7b) / /: nombre magique
crc_ok <= 1'b1;
autre
crc_ok <= 1'b0;
fin
toujours @ (posedge clk)
commencer
if (! reset_n)
crc_buffer <= `BUFFER_INIT_VALUE;
autre
if (FCS_start_check)
crc_buffer <= count_crc (données, crc_buffer);
autre
crc_buffer <= `BUFFER_INIT_VALUE;
fin
endmodule
module rx_buffer (
clk,
reset_n,
rx_data,
data_tap,
données,
data_en
);
input clk, data_en, reset_n;
input [7:0] rx_data;
sortie [7:0] data_tap,
des données;
reg [7:0] data_tap;
reg [7:0] data_temp;
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
data_tap <= 8'b00000000;
autre
data_tap <= rx_data;
fin
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
data_temp <= 8'b00000000;
autre
data_temp <= data_tap;
fin
assign = data_en données?data_temp: 8'bzzzzzzzz;
endmodule«définir INITIAL_COUNT 12'b000000000000
«définir MAX_COUNT 12'b101111011100
«définir STATUS_RESET 16'b0000000000000000
«définir STATUS_ERROR 15'b000000000000000
«définir eo_DA 12'b000000001011
«définir GET_CRC_OUT 12'b000000001101
«définir CRCO_ZERO 9'b000000000
«définir Rx_IDLE 4'b000
«définir SFD_detect 4'b001
«définir Rx_RUN 4'b010
«définir Rx_HOLD 4'b011
«définir Rx_STOP 4'b100
«définir WRITE_STATUS 4'b101
«définir HOLD1_STATUS 4'b110
«définir HOLD2_STATUS 4'b111
module rx_sm (
clk,
reset_n,
rx_dv,
rx_error,
SFD_detected,
address_match,
multicast,
la diffusion,
crc_ok,
SFD_start_detect,
data_en,
FCS_start_check,
last_data,
data_valid,
rx_status_valid_n,
rx_status
);
input clk,
reset_n,
rx_dv,
rx_error,
SFD_detected,
address_match,
multicast,
la diffusion,
crc_ok;
sortie SFD_start_detect,
data_en,
FCS_start_check,
last_data,
data_valid,
rx_status_valid_n;
sortie [15:0] rx_status;
reg SFD_start_detect,
FCS_start_check,
data_en,
last_data,
broadcast_temp,
multicast_temp,
address_match_temp,
data_valid,
rx_error_temp,
sending_data_n_status,
rx_status_valid_n;
reg [3:0] rx_sm_state;
reg [12:0] nibble_count,
nibble_count_temp;
reg [15:0] rx_status;
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
rx_sm_state <= `Rx_IDLE;
autre
if (rx_error)
commencer
rx_error_temp <= 1'b1;
rx_sm_state <= `Rx_HOLD;
fin
autre
si ((nibble_count_temp 2'b10) == `MAX_COUNT)
commencer
rx_error_temp <= 1'b1;
rx_sm_state <= `Rx_HOLD;
fin
autre
cas (rx_sm_state)
»Rx_IDLE:
commencer
if (rx_dv)
commencer
rx_sm_state <= `SFD_detect;
SFD_start_detect <= 1'b1;
fin
autre
commencer
SFD_start_detect <= 1'b0;
data_en <= 1'b0;
FCS_start_check <= 1'b0;
rx_status_valid_n <= 1'b1;
rx_status <= `STATUS_RESET;
last_data <= 1'b0;
data_valid <= 1'b0;
sending_data_n_status <= 1'b0;
rx_sm_state <= `Rx_IDLE;
rx_error_temp <= 1'b0;
fin
fin
»SFD_detect:
commencer
if (! rx_dv)
rx_sm_state <= `Rx_HOLD;
autre
if (SFD_detected)
commencer
SFD_start_detect <= 1'b0;
FCS_start_check <= 1'b1;
data_valid <= 1'b1;
sending_data_n_status <= 1'b1;
data_en <= 1'b1;
rx_sm_state <= `Rx_RUN;
fin
autre
rx_sm_state <= `SFD_detect;
fin
»Rx_RUN:
commencer
if (! rx_dv)
commencer
last_data <= 1'b1;
rx_sm_state <= `Rx_HOLD;
fin
autre
rx_sm_state <= `Rx_RUN;
fin
»Rx_HOLD:
commencer
last_data <= 1'b0;
data_valid <= 1'b0;
data_en <= 1'b0;
rx_sm_state <= `Rx_STOP;
fin
»Rx_STOP:
commencer
FCS_start_check <= 1'b0;
rx_sm_state <= `WRITE_STATUS;
fin
»WRITE_STATUS:
commencer
rx_status_valid_n <= 1'b0;
rx_status [0] <= rx_error_temp;
rx_status [1] <= address_match_temp;
rx_status [2] <= (broadcast_temp | multicast_temp);
rx_status [3] <= crc_ok;
rx_status [15:4] <= nibble_count 1'b1;
rx_sm_state <= `HOLD1_STATUS;
fin
»HOLD1_STATUS:
commencer
rx_sm_state <= `HOLD2_STATUS;
fin
»HOLD2_STATUS:
rx_sm_state <= `Rx_IDLE;
par défaut:
rx_sm_state <= `Rx_IDLE;
endcase
fin
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
nibble_count_temp <= `INITIAL_COUNT;
autre
if (! data_en)
nibble_count_temp <= `INITIAL_COUNT;
autre
nibble_count_temp <= (nibble_count_temp 1'b1);
fin
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
nibble_count <= `INITIAL_COUNT;
autre
if (data_en)
nibble_count <= nibble_count_temp;
autre
nibble_count <= nibble_count;
fin
toujours @ (posedge clk)
commencer
if (! reset_n)
commencer
broadcast_temp <= 1'b0;
multicast_temp <= 1'b0;
address_match_temp <= 1'b0;
fin
autre
if (! sending_data_n_status)
commencer
broadcast_temp <= 1'b0;
multicast_temp <= 1'b0;
address_match_temp <= 1'b0;
fin
autre
if (address_match)
commencer
broadcast_temp <= émission;
multicast_temp <= multicast;
address_match_temp <= address_match;
fin
autre
commencer
broadcast_temp <= broadcast_temp;
multicast_temp <= multicast_temp;
address_match_temp <= address_match_temp;
fin
fin
endmodule
module SFD_detector (
clk,
reset_n,
data_tap,
SFD_start_detect,
SFD_detected
);
input clk, SFD_start_detect, reset_n;
input [3:0] data_tap;
SFD_detected de sortie;
reg SFD_detected;
toujours @ (posedge clk ou negedge reset_n)
commencer
if (! reset_n)
SFD_detected <= 1'b0;
autre
if (! SFD_start_detect)
SFD_detected <= 1'b0;
autre
commencer
if (data_tap == 4'b1101)
SFD_detected <= 1'b1;
autre
SFD_detected <= 1'b0;
fin
fin
endmodulemodule txethmac (
tx_data,
tx_sof,
tx_eof,
tx_underrun,
full_duplex,
reset_n,
crs,
coll,
tx_clk,
tx_data_used,
tx_done,
tx_abort,
tx_retransmit,
tx_status,
tx_status_valid_n,
TxD,
tx_en,
tx_er
);
/ / Du DMA
input [7:0] tx_data;
tx_sof d'entrée;
tx_eof d'entrée;
tx_underrun d'entrée;
full_duplex d'entrée;
reset_n d'entrée;
/ / De MII
crs entrée;
entrée coll;
tx_clk d'entrée;
/ / Pour MII
sortie [7:0] TXD;
tx_en de sortie;
tx_er de sortie;
/ / Pour DMA
tx_data_used de sortie;
tx_done de sortie;
tx_abort de sortie;
tx_retransmit de sortie;
sortie [6:0] tx_status;
tx_status_valid_n de sortie;
wire [7:0] data;
transmit_error fil;
transmit_enable fil;
compute_crc fil;
wire [7:0] crc;
wire [2:0] data_select;
transmit_available_p fil;
transmit_new_p fil;
excess_deferral fil;
transmit_preamble fil;
transmit_sfd fil;
wire [3:0] coll_attempt;
late_coll fil;
excessive_coll fil;
coll_event_p fil;
transmit_64byte fil;
transmit_fcs fil;
wire [11:0] count_length;
wire [3:0] count_fcs;
excessive_length fil;
wire [3:0] count_jam;
wire [9:0] hasard;
backoff_p fil;
start_backoff fil;
/ / instancie modules
fifo_synch tx_1 (
. data (données),
. transmit_enable (transmit_enable),
. transmit_error (transmit_error),
. clk (tx_clk),
. TXD (TXD),
. tx_en (tx_en),
. tx_er (tx_er)
);
ifg_timer tx_2 (
. crs (crs),
. full_duplex (full_duplex),
. transmit_enable (transmit_enable),
. clk (tx_clk),
. reset_n (reset_n),
. transmit_available_p (transmit_available_p)
);
defer_counter tx_3 (
. transmit_available_p (transmit_available_p),
. transmit_new_p (transmit_new_p),
. clk (tx_clk),
. reset_n (reset_n),
. excess_deferral (excess_deferral)
);
frame_length_counter tx_4 (
. transmit_enable (transmit_enable),
. transmit_fcs (transmit_fcs),
. clk (tx_clk),
. reset_n (reset_n),
. count_length (count_length),
. count_fcs (count_fcs),
. excessive_length (excessive_length),
. transmit_64byte (transmit_64byte)
);
/ / coll_counter tx_5 (
/ /. transmit_new_p (transmit_new_p),
/ /. transmit_enable (transmit_enable),
/ /. Transmit_preamble (transmit_preamble),
/ /. Transmit_sfd (transmit_sfd),
/ /. Transmit_64byte (transmit_64byte),
/ /. Clk (tx_clk),
/ /. Reset_n (reset_n),
/ /. Coll (coll),
/ /. Full_duplex (full_duplex),
/ /. Coll_event_p (coll_event_p),
/ /. Late_coll (late_coll),
/ /. Excessive_coll (excessive_coll),
/ /. Coll_attempt (coll_attempt)
/ /);
/ / random_number_gen tx_6 (
/ /. Coll_attempt (coll_attempt),
/ /. Clk (tx_clk),
/ /. Reset_n (reset_n),
/ /. Aléatoire (random)
/ /);
/ / backoff_timer tx_7 (
/ /. start_backoff (start_backoff),
/ /. aléatoire (random),
/ /. clk (tx_clk),
/ /. reset_n (reset_n),
/ /. backoff_p (backoff_p)
/ /);
/ / jam_timer tx_8 (
/ /. coll_event_p (coll_event_p),
/ /. clk (tx_clk),
/ /. reset_n (reset_n),
/ /. count_jam (count_jam)
/ /);
crc_gen tx_9 (
. compute_crc (compute_crc),
. data (données),
. clk (tx_clk),
. reset_n (reset_n),
. crc (crc)
);
data_mux tx_10 (
. data_select (data_select),
. data_in (tx_data),
. crc (CRC),
. data_out (données)
);
tx_state_machine tx_11 (
. tx_sof (tx_sof),
. tx_eof (tx_eof),
. tx_underrun (tx_underrun),
. clk (tx_clk),
. reset_n (reset_n),
. transmit_available_p (transmit_available_p),
. excess_deferral (excess_deferral),
. coll_event_p (coll_event_p),
. late_coll (late_coll),
. excessive_coll (excessive_coll),
. backoff_p (backoff_p),
. count_length (count_length),
. count_fcs (count_fcs),
. excessive_length (excessive_length),
. count_jam (count_jam),
. tx_data_used (tx_data_used),
. tx_done (tx_done),
. tx_abort (tx_abort),
. tx_retransmit (tx_retransmit),
. tx_status (tx_status),
. tx_status_valid_n (tx_status_valid_n),
. transmit_new_p (transmit_new_p),
. transmit_enable (transmit_enable),
. transmit_preamble (transmit_preamble),
. transmit_sfd (transmit_sfd),
. transmit_fcs (transmit_fcs),
. transmit_error (transmit_error),
. start_backoff (start_backoff),
. compute_crc (compute_crc),
. data_select (data_select)
);«définir CRC_INIT_VALUE (32'hFFFF_FFFF)
«définir CRC_IDLE (2'b00)
«définir CRC_RUN (2'b01)
«définir CRC_STOP (2'b11)
module crc_gen (
compute_crc,
données,
clk,
reset_n,
crc
);
compute_crc d'entrée;
input [7:0] data;
input clk;
reset_n d'entrée;
sortie [7:0] crc;
reg [1:0] state_crc;
reg [31:0] crc_buffer;
reg [2:0] crc_end;
fonction [31:0] count_crc, / /, la première série de données est peu d [0]
input [3:0] d;
input [31:0] c;
reg [31:0] new_crc;
commencer
new_crc [0] = d [3] ^ c [28];
new_crc [1] = d [2] ^ d [3] ^ c [28] ^ c [29];
new_crc [2] = d [1] ^ d [2] ^ d [3] ^ c [28] ^ c [29] ^ c [30];
new_crc [3] = d [0] ^ d [1] ^ d [2] ^ c [29] ^ c [30] ^ c [31];
new_crc [4] = d [0] ^ d [1] ^ d [3] ^ c [0] ^ c [28] ^ c [30] ^ c [31];
new_crc [5] = d [0] ^ d [2] ^ d [3] ^ c [1] ^ c [28] ^ c [29] ^ c [31];
new_crc [6] = d [1] ^ d [2] ^ c [2] ^ c [29] ^ c [30];
new_crc [7] = d [0] ^ d [1] ^ d [3] ^ c [3] ^ c [28] ^ c [30] ^ c [31];
new_crc [8] = d [0] ^ d [2] ^ d [3] ^ c [4] ^ c [28] ^ c [29] ^ c [31];
new_crc [9] = d [1] ^ d [2] ^ c [5] ^ c [29] ^ c [30];
new_crc [10] = d [0] ^ d [1] ^ d [3] ^ c [6] ^ c [28] ^ c [30] ^ c [31];
new_crc [11] = d [0] ^ d [2] ^ d [3] ^ c [7] ^ c [28] ^ c [29] ^ c [31];
new_crc [12] = d [1] ^ d [2] ^ d [3] ^ c [8] ^ c [28] ^ c [29] ^ c [30];
new_crc [13] = d [0] ^ d [1] ^ d [2] ^ c [9] ^ c [29] ^ c [30] ^ c [31];
new_crc [14] = d [0] ^ d [1] ^ c [10] ^ c [30] ^ c [31];
new_crc [15] = d [0] ^ c [11] ^ c [31];
new_crc [16] = d [3] ^ c [12] ^ c [28];
new_crc [17] = d [2] ^ c [13] ^ c [29];
new_crc [18] = d [1] ^ c [14] ^ c [30];
new_crc [19] = d [0] ^ c [15] ^ c [31];
new_crc [20] = c [16];
new_crc [21] = c [17];
new_crc [22] = d [3] ^ c [18] ^ c [28];
new_crc [23] = d [2] ^ d [3] ^ c [19] ^ c [28] ^ c [29];
new_crc [24] = d [1] ^ d [2] ^ c [20] ^ c [29] ^ c [30];
new_crc [25] = d [0] ^ d [1] ^ c [21] ^ c [30] ^ c [31];
new_crc [26] = d [0] ^ d [3] ^ c [22] ^ c [28] ^ c [31];
new_crc [27] = d [2] ^ c [23] ^ c [29];
new_crc [28] = d [1] ^ c [24] ^ c [30];
new_crc [29] = d [0] ^ c [25] ^ c [31];
new_crc [30] = c [26];
new_crc [31] = c [27];
count_crc = new_crc;
fin
endfunction
attribuer crc [7] = ~ crc_buffer [24];
attribuer crc [6] = ~ crc_buffer [25];
attribuer crc [5] = ~ crc_buffer [26];
crc céder [4] = ~ crc_buffer [27];
attribuer crc [3] = ~ crc_buffer [28];
attribuer crc [2] = ~ crc_buffer [29];
attribuer crc [1] = ~ crc_buffer [30];
attribuer crc [0] = ~ crc_buffer [31];
toujours @ (posedge clk ou negedge reset_n)
if (! reset_n)
state_crc <= `CRC_IDLE;
autre
cas (state_crc)
»CRC_IDLE:
if (compute_crc)
commencer
state_crc <= `CRC_RUN;
crc_buffer <= count_crc (données, CRC_INIT_VALUE »);
fin
autre
commencer
state_crc <= `CRC_IDLE;
crc_buffer <= 32'h0000_0000;
crc_end <= 3'd0;
fin
»CRC_RUN:
if (! Compute_crc)
commencer
state_crc <= `CRC_STOP;
crc_buffer <= crc_buffer <<8;
fin
autre
commencer
state_crc <= `CRC_RUN;
crc_buffer <= count_crc (données, crc_buffer);
fin
»CRC_STOP:
if (crc_end == 3'110)
commencer
state_crc <= `CRC_IDLE;
crc_buffer <= 32'h0000_0000;
fin
autre
commencer
state_crc <= `CRC_STOP;
crc_buffer <= crc_buffer <<4;
crc_end <= crc_end 1'b1;
fin
endcase
endmodule
«définir PATTERN_PREAMBLE (8'b01010101)
«définir PATTERN_SFD (8'b11010101)
module data_mux (
data_select,
data_in,
crc,
data_out,
count_length
);
input [2:0] data_select;
input [7:0] data_in;
input [7:0] crc;
input [7:0] count_length;
sortie [7:0] data_out;
reg [7:0] data_out;
toujours @ (data_select ou data_in ou crc)
cas (data_select)
3'b000: data_out = data_in;
3'b001: data_out = `PATTERN_PREAMBLE;
3'b010: data_out = `PATTERN_SFD;
3'b011: data_out = crc;
3'b100: data_out = src_add;
3'b101: data_out = dst_add;
3'b110: data_out = count_length;
par défaut: data_out = 8'h00;
endcase
endmodule
module fifo_synch (
données,
transmit_enable,
transmit_error,
clk,
TxD,
tx_en,
tx_er
);
input [7:0] data;
transmit_enable d'entrée;
transmit_error d'entrée;
input clk;
sortie [7:0] TXD;
tx_en de sortie;
tx_er de sortie;
reg [7:0] TXD;
reg tx_en;
reg tx_er;
toujours @ (posedge clk)
if (transmit_enable)
commencer
TXD <= data;
tx_en <= 1'b1;
tx_er <= transmit_error;
fin
autre
commencer
TXD <= 8'h00;
tx_en <= 1'b0;
tx_er <= 1'b0;
fin
endmodule«définir COUNT_LENGTH_IDLE (2'b00)
«définir COUNT_LENGTH_RUN (2'b01)
«définir COUNT_LENGTH_FCS (2'b11)
«définir MIN_LENGTH (12'd144)
«définir max_length (12'd3052)
module frame_length_counter (
transmit_enable,
transmit_fcs,
clk,
reset_n,
count_length,
count_fcs,
excessive_length,
transmit_64byte
);
transmit_enable d'entrée;
transmit_fcs d'entrée;
input clk;
reset_n d'entrée;
sortie [11:0] count_length;
sortie [3:0] count_fcs;
excessive_length de sortie;
transmit_64byte de sortie;
reg [11:0] count_length;
reg [3:0] count_fcs;
reg excessive_length;
reg transmit_64byte;
reg [1:0] state_length;
fonction [11:0] inc_length;
input [11:0] count_length;
commencer
inc_length = count_length 1'b1;
fin
endfunction
toujours @ (posedge clk ou negedge reset_n)
if (! reset_n)
commencer
state_length <= `COUNT_LENGTH_IDLE;
count_length <= 12'd0;
count_fcs <= 4'd0;
fin
autre
cas (state_length)
»COUNT_LENGTH_IDLE:
if (transmit_enable)
commencer
state_length <= `COUNT_LENGTH_RUN;
count_length <= 12'd1;
fin
autre
state_length <= `COUNT_LENGTH_IDLE;
»COUNT_LENGTH_RUN:
if (! Transmit_enable)
state_length <= `COUNT_LENGTH_IDLE;
autre
if (transmit_fcs)
commencer
state_length <= `COUNT_LENGTH_FCS;
count_length <= inc_length (count_length);
count_fcs <= 4'd1;
fin
autre
commencer
state_length <= `COUNT_LENGTH_RUN;
count_length <= inc_length (count_length);
fin
»COUNT_LENGTH_FCS:
if (! Transmit_enable)
state_length <= `COUNT_LENGTH_IDLE;
autre
commencer
state_length <= `COUNT_LENGTH_FCS;
count_length <= inc_length (count_length);
count_fcs <= (count_fcs 1'b1);
fin
endcase
toujours @ (count_length)
commencer
transmit_64byte = (count_length> »MIN_LENGTH-1)?1'b1: 1'b0;
excessive_length = (count_length> »max_length-1)?1'b1: 1'b0;
fin
endmodule«définir IFG_LENGTH_1 (5'd15)
«définir IFG_LENGTH_2 (5'd22)
«définir IFG_IDLE (1'b0)
«définir IFG_RUN (1'b1)
module ifg_timer (
crs,
full_duplex,
transmit_enable,
clk,
reset_n,
transmit_available_p
);
crs entrée;
full_duplex d'entrée;
transmit_enable d'entrée;
input clk;
reset_n d'entrée;
transmit_available_p de sortie;
reg transmit_available_p;
reg [4:0] count_ifg;
reg state_ifg;
Fonction [4:0] inc_ifg;
input [4:0] count_ifg;
commencer
inc_ifg = count_ifg 1'b1;
fin
endfunction
toujours @ (posedge clk ou negedge reset_n)
if (! reset_n)
state_ifg <= `IFG_IDLE;
autre
if (full_duplex)
cas (state_ifg)
»IFG_IDLE:
if (! Transmit_enable)
commencer
state_ifg <= `IFG_RUN;
count_ifg <= 5'd1;
transmit_available_p <= 1'b0;
fin
autre
commencer
state_ifg <= `IFG_IDLE;
count_ifg <= 5'd0;
transmit_available_p <= 1'b0;
fin
»IFG_RUN:
if (transmit_enable)
state_ifg <= `IFG_IDLE;
autre
if (count_ifg == `IFG_LENGTH_2-1)
commencer
state_ifg <= `IFG_IDLE;
transmit_available_p <= 1'b1;
fin
autre
commencer
state_ifg <= `IFG_RUN;
count_ifg <= inc_ifg (count_ifg);
fin
endcase
autre
cas (state_ifg)
»IFG_IDLE:
if (! Crs)
commencer
state_ifg <= `IFG_RUN;
count_ifg <= 5'd1;
transmit_available_p <= 1'b0;
fin
autre
commencer
state_ifg <= `IFG_IDLE;
count_ifg <= 5'd0;
transmit_available_p <= 1'b0;
fin
»IFG_RUN:
if (crs & & (count_ifg <=` IFG_LENGTH_1-1))
state_ifg <= `IFG_IDLE;
autre
if (count_ifg == `IFG_LENGTH_2-1)
commencer
state_ifg <= `IFG_IDLE;
transmit_available_p <= 1'b1;
fin
autre
commencer
state_ifg <= `IFG_RUN;
count_ifg <= inc_ifg (count_ifg);
fin
endcase
endmodule
«définir TRANSMIT_IDLE (4'b0000)
«définir NEW_TRANSMIT (4'b0001)
«définir WAIT_TRANSMIT (4'b0011)
«définir TRANSMIT_PREAMBLE (4'b0010)
«définir TRANSMIT_SFD (4'b0110)
«définir TRANSMIT_DATA (4'b0111)
«définir TRANSMIT_PAD (4'b0101)
«définir TRANSMIT_FCS (4'b0100)
«définir WAIT_DONE (4'b1100)
«définir TRANSMIT_DONE (4'b1101)
«définir TRANSMIT_JAM (4'b1111)
«définir WAIT_BACKOFF (4'b1110)
«définir WAIT_ABORT (4'b1010)
«définir TRANSMIT_ABORT (4'b1011)
«définir WRITE_STATUS (4'b1001)
/ / `define (4'b1000)
«définir PREAMBLE_LENGTH (12'd15)
«définir SFD_LENGTH (12'd1)
«définir DATA_LENGTH (12'd120)
«définir FCS_LENGTH (4'd
<img src="http://www.edaboard.com/images/smiles/icon_cool.gif" alt="Cool" border="0" />«définir JAM_LENGTH (4'd
<img src="http://www.edaboard.com/images/smiles/icon_cool.gif" alt="Cool" border="0" />«définir WIDTH_STATUS 7
module tx_state_machine (
tx_sof,
tx_eof,
tx_underrun,
clk,
reset_n,
transmit_available_p,
excess_deferral,
coll_event_p,
late_coll,
excessive_coll,
backoff_p,
count_length,
count_fcs,
excessive_length,
count_jam,
tx_data_used,
tx_done,
tx_abort,
tx_retransmit,
tx_status,
tx_status_valid_n,
transmit_new_p,
transmit_enable,
transmit_preamble,
transmit_sfd,
transmit_fcs,
transmit_error,
start_backoff,
compute_crc,
data_select
);
tx_sof d'entrée;
tx_eof d'entrée;
tx_underrun d'entrée;
input clk;
reset_n d'entrée;
transmit_available_p d'entrée;
excess_deferral d'entrée;
excessive_length d'entrée;
excessive_coll d'entrée;
late_coll d'entrée;
coll_event_p d'entrée;
backoff_p d'entrée;
input [11:0] count_length;
input [3:0] count_fcs;
input [3:0] count_jam;
tx_data_used de sortie;
tx_done de sortie;
tx_abort de sortie;
tx_retransmit de sortie;
sortie [ `WIDTH_STATUS-1: 0] tx_status;
tx_status_valid_n de sortie;
transmit_new_p de sortie;
transmit_enable de sortie;
transmit_preamble de sortie;
transmit_sfd de sortie;
transmit_fcs de sortie;
transmit_error de sortie;
start_backoff de sortie;
compute_crc de sortie;
sortie [2:0] data_select;
reg tx_data_used;
reg tx_done;
reg tx_abort;
reg tx_retransmit;
/ / Reg [ `WIDTH_STATUS-1: 0] tx_status;
reg tx_status_valid_n;
reg transmit_new_p;
reg transmit_enable;
reg transmit_preamble;
reg transmit_sfd;
reg transmit_fcs;
reg transmit_error;
reg start_backoff;
reg compute_crc;
reg [2:0] data_select;
reg [3:0] current_tx_state;
reg [3:0] next_tx_state;
toujours @ (posedge clk ou negedge reset_n)
if (! reset_n)
current_tx_state <= `TRANSMIT_IDLE;
autre
current_tx_state <= next_tx_state;
toujours @ (current_tx_state ou tx_sof ou tx_eof ou tx_underrun ou
transmit_available_p ou excess_deferral ou excessive_length ou
excessive_coll ou late_coll ou coll_event_p ou backoff_p ou
count_length ou count_fcs ou count_jam)
cas (current_tx_state)
»TRANSMIT_IDLE:
if (tx_sof)
next_tx_state = `NEW_TRANSMIT;
autre
next_tx_state = `TRANSMIT_IDLE;
»NEW_TRANSMIT:
if (! Tx_sof)
next_tx_state = `TRANSMIT_IDLE;
autre
next_tx_state = `WAIT_TRANSMIT;
»WAIT_TRANSMIT:
if (! Tx_sof)
next_tx_state = `TRANSMIT_IDLE;
autre
if (excess_deferral)
next_tx_state = `WAIT_ABORT;
autre
if (transmit_available_p)
next_tx_state = `TRANSMIT_PREAMBLE;
autre
next_tx_state = `WAIT_TRANSMIT;
»TRANSMIT_PREAMBLE:
if (! Tx_sof)
next_tx_state = `TRANSMIT_IDLE;
autre
if (count_length == `PREAMBLE_LENGTH-1)
next_tx_state = `TRANSMIT_SFD;
autre
next_tx_state = `TRANSMIT_PREAMBLE;
»TRANSMIT_SFD:
if (! Tx_sof)
next_tx_state = `TRANSMIT_IDLE;
autre
next_tx_state = `TRANSMIT_DATA;
»TRANSMIT_DATA:
if (coll_event_p)
next_tx_state = `TRANSMIT_JAM;
autre
if (tx_underrun | | excessive_length)
next_tx_state = `WAIT_ABORT;
autre
if (tx_eof)
commencer
if (count_length <(PREAMBLE_LENGTH ` ` SFD_LENGTH `DATA_LENGTH-1))
next_tx_state = `TRANSMIT_PAD;
autre
next_tx_state = `TRANSMIT_FCS;
fin
autre
next_tx_state = `TRANSMIT_DATA;
»TRANSMIT_PAD:
if (coll_event_p)
next_tx_state = `TRANSMIT_JAM;
autre
if (count_length == (PREAMBLE_LENGTH ` ` SFD_LENGTH `DATA_LENGTH-1))
next_tx_state = `TRANSMIT_FCS;
autre
next_tx_state = `TRANSMIT_PAD;
»TRANSMIT_FCS:
if (coll_event_p)
next_tx_state = `TRANSMIT_JAM;
autre
if (excessive_length)
next_tx_state = `WAIT_ABORT;
autre
if (count_fcs == `FCS_LENGTH-1)
next_tx_state = `WAIT_DONE;
autre
next_tx_state = `TRANSMIT_FCS;
»TRANSMIT_JAM:
if (count_jam ==` JAM_LENGTH-3)
commencer
if (late_coll | | excessive_coll)
next_tx_state = `WAIT_ABORT;
autre
next_tx_state = `WAIT_BACKOFF;
fin
autre
next_tx_state = `TRANSMIT_JAM;
»WAIT_BACKOFF:
if (backoff_p)
next_tx_state = `WAIT_TRANSMIT;
autre
next_tx_state = `WAIT_BACKOFF;
»WAIT_DONE:
if (coll_event_p)
next_tx_state = `TRANSMIT_JAM;
autre
if (excessive_length)
next_tx_state = `WAIT_ABORT;
autre
next_tx_state = `TRANSMIT_DONE;
»TRANSMIT_DONE: next_tx_state =` WRITE_STATUS;
»WAIT_ABORT: next_tx_state =` TRANSMIT_ABORT;
»TRANSMIT_ABORT: next_tx_state =` WRITE_STATUS;
»WRITE_STATUS: next_tx_state =` TRANSMIT_IDLE;
par défaut: next_tx_state = `TRANSMIT_IDLE;
endcase
toujours @ (current_tx_state)
cas (current_tx_state)
»TRANSMIT_IDLE:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»NEW_TRANSMIT:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b1;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»WAIT_TRANSMIT:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_PREAMBLE:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b1;
transmit_preamble = 1'b1;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b001;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_SFD:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b1;
transmit_preamble = 1'b0;
transmit_sfd = 1'b1;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b010;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_DATA:
commencer
tx_data_used = 1'b1;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b1;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b1;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_PAD:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b1;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b001;
compute_crc = 1'b1;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_FCS:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b1;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b1;
start_backoff = 1'b0;
data_select = 3'b011;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»WAIT_DONE:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_DONE:
commencer
tx_data_used = 1'b0;
tx_done = 1'b1;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_JAM:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b1;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b001;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»WAIT_BACKOFF:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b1;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b1;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»WAIT_ABORT:
commencer
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
fin
»TRANSMIT_ABORT:
commencer
tx_data_used = 1'b0;tx_done = 1'b0;
tx_abort = 1'b1;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
end
`WRITE_STATUS :
begin
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b0;
end
default :
begin
tx_data_used = 1'b0;
tx_done = 1'b0;
tx_abort = 1'b0;
tx_retransmit = 1'b0;
transmit_new_p = 1'b0;
transmit_enable = 1'b0;
transmit_preamble = 1'b0;
transmit_sfd = 1'b0;
transmit_fcs = 1'b0;
start_backoff = 1'b0;
data_select = 3'b000;
compute_crc = 1'b0;
tx_status_valid_n = 1'b1;
end
endcase
assign tx_status [0] = excess_deferral;
assign tx_status [1] = late_coll;
assign tx_status [2] = excessive_coll;
assign tx_status [3] = 1'b0;
assign tx_status [4] = excessive_length;
assign tx_status [5] = (excess_deferral | late_coll | excessive_coll |
tx_underrun | excessive_length);
assign tx_status [6] = ~(excess_deferral | late_coll | excessive_coll |
tx_underrun | excessive_length);
always @(posedge clk)
if (tx_underrun)
transmit_error <= 1'b1; autretransmit_error <= 1'b0;
endmodule