📄 arp_send.v
字号:
`define REQUEST 16'h0001
`define REPLY 16'h0002
/*************************
arp_send.v
Generates ARP packets based on IP and MAC addresses that need to be sent.
Inputs:
clk
reset
send_ip_addr_reply (from arp_rcv)
send_mac_addr_reply (from arp_rcv)
send_ip_addr_request (from send_buffer)
SPA (from ip_send)
SHA (from ip_send)
request_en (a bit that is high if a request needs to be sent)
reply_en (a bit that is high if a reply needs to be sent)
send_buffer_ready (enables sending of ARP packets to the send_buffer module)
Outputs:
arp_valid (to send_buffer)
arp_data (to send_buffer)
reply_ready (to arp_rcv)
request_ready (to send_buffer)
arp_mac_addr (to send_buffer)
jdp45 mjk64 hmm32
ece576 UDP project
cornell univ 11/2007
**************************/
module arp_send(
input clk,
input reset,
input [31:0] send_ip_addr_reply,
input [47:0] send_mac_addr_reply,
input [31:0] send_ip_addr_request,
input [31:0] SPA,
input [47:0] SHA,
input request_en,
input reply_en,
input send_buffer_ready,
output reg arp_valid,
output reg [31:0] arp_data,
output reply_ready,
output request_ready,
output reg [47:0] arp_mac_addr
);
reg [2:0] word_counter; //increments when ARP data is being received in 7 separate 32-bit words
reg [15:0] HTYPE, PTYPE, OPER;
reg [7:0] HLEN, PLEN;
reg [47:0] THA;
reg [31:0] TPA;
reg request_buffer_valid, reply_buffer_valid, clear_to_send;
reg [31:0] ip_request_buffer, ip_reply_buffer;
reg [47:0] mac_reply_buffer;
//only ready for new packets when buffers do not have valid data in them
assign request_ready = ~request_buffer_valid;
assign reply_ready = ~reply_buffer_valid;
always @(posedge clk) begin
if (reset) begin
// initialization
word_counter <= 3'd0;
HTYPE <= 16'h0001;
PTYPE <= 16'h0800;
HLEN <= 8'h06;
PLEN <= 8'h04;
OPER <= 16'h0;
THA <= 48'h0;
TPA <= 32'h0;
clear_to_send <= 1'b0;
request_buffer_valid <= 1'b0;
reply_buffer_valid <= 1'b0;
ip_request_buffer <= 32'b0;
ip_reply_buffer <= 32'b0;
mac_reply_buffer <= 32'b0;
arp_mac_addr <= 48'b0;
arp_valid <= 1'b0;
arp_data <= 32'b0;
end
else begin
case ({request_en, reply_en})
2'b00:
begin
//check the buffers for data
if ((send_buffer_ready) && (!clear_to_send) && (!arp_valid)) begin
if (request_buffer_valid) begin
OPER <= `REQUEST;
TPA <= ip_request_buffer;
THA <= 48'h0;
request_buffer_valid <= 1'b0;
clear_to_send <= 1'b1;
end
else if ((reply_buffer_valid) && (!request_buffer_valid)) begin
OPER <= `REPLY;
TPA <= ip_reply_buffer;
THA <= mac_reply_buffer;
reply_buffer_valid <= 1'b0;
clear_to_send <= 1'b1;
end
end
else begin
clear_to_send <= 1'b0;
end
end
2'b01:
begin
if ((send_buffer_ready) && (!clear_to_send) && (!arp_valid)) begin
OPER <= `REPLY;
TPA <= send_ip_addr_reply;
THA <= send_mac_addr_reply;
clear_to_send <= 1'b1;
end
else begin
ip_reply_buffer <= send_ip_addr_reply;
reply_buffer_valid <= 1'b1;
mac_reply_buffer <= send_mac_addr_reply;
clear_to_send <= 1'b0;
end
end
2'b10:
begin
if ((send_buffer_ready) && (!clear_to_send) && (!arp_valid)) begin
OPER <= `REQUEST;
TPA <= send_ip_addr_request;
THA <= 48'h0;
clear_to_send <= 1'b1;
end
else begin
ip_request_buffer <= send_ip_addr_request;
request_buffer_valid <= 1'b1;
clear_to_send <= 1'b0;
end
end
2'b11:
begin
if ((send_buffer_ready) && (!clear_to_send) && (!arp_valid)) begin
OPER <= `REQUEST;
TPA <= send_ip_addr_request;
THA <= 48'h0;
clear_to_send <= 1'b1;
end
else begin
ip_request_buffer <= send_ip_addr_request;
request_buffer_valid <= 1'b1;
clear_to_send <= 1'b0;
end
ip_reply_buffer <= send_ip_addr_reply;
reply_buffer_valid <= 1'b1;
mac_reply_buffer <= send_mac_addr_reply;
end
default:
begin
end
endcase
//Data Tx state machine:
//send out ARP packets one word at a time when send_buffer_ready is high,
//and set the valid bit high when doing so. increment through the
//words using word_counter.
if (send_buffer_ready) begin
case (word_counter)
3'd0:
begin
if (clear_to_send) begin //packet is beginning to be sent
arp_data <= {HTYPE, PTYPE};
arp_valid <= 1'b1;
word_counter <= word_counter + 1;
clear_to_send <= 1'b0;
//send MAC address independently of packet
if (OPER == `REQUEST) begin
arp_mac_addr <= 48'hFFFFFFFFFFFF;
end
else begin
arp_mac_addr <= THA;
end
end
else begin //packet just finished being sent... now we wait for another clear_to_send
arp_valid <= 1'b0;
end
end
3'd1:
begin
arp_data <= {HLEN, PLEN, OPER};
arp_valid <= 1'b1;
word_counter <= word_counter + 1;
end
3'd2:
begin
arp_data <= SHA[47:16];
arp_valid <= 1'b1;
word_counter <= word_counter + 1;
end
3'd3:
begin
arp_data <= {SHA[15:0], SPA[31:16]};
arp_valid <= 1'b1;
word_counter <= word_counter + 1;
end
3'd4:
begin
arp_data <= {SPA[15:0], THA[47:32]};
arp_valid <= 1'b1;
word_counter <= word_counter + 1;
end
3'd5:
begin
arp_data <= THA[31:0];
arp_valid <= 1'b1;
word_counter <= word_counter + 1;
end
3'd6:
begin
arp_data <= TPA;
arp_valid <= 1'b1;
word_counter <= 3'd0;
end
default: //should not reach this state
begin
arp_data <= 32'b0;
arp_valid <= 1'b0;
word_counter <= 3'd0;
end
endcase
end
else begin
arp_valid <= 1'b0;
//word_counter <= 3'd0;
end
end
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -