URL
https://opencores.org/ocsvn/10_100m_ethernet-fifo_convertor/10_100m_ethernet-fifo_convertor/trunk
Subversion Repositories 10_100m_ethernet-fifo_convertor
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 9 to Rev 10
- ↔ Reverse comparison
Rev 9 → Rev 10
/10_100m_ethernet-fifo_convertor/trunk/doc/10_100M_Ethernet-FIFO_Convertor.pdf
File deleted
\ No newline at end of file
/10_100m_ethernet-fifo_convertor/trunk/rtl/verilog/RxModule.v
File deleted
\ No newline at end of file
/10_100m_ethernet-fifo_convertor/trunk/rtl/verilog/common.v
File deleted
\ No newline at end of file
/10_100m_ethernet-fifo_convertor/verilog/CRC_Module.v
0,0 → 1,64
module CRC_Module(Clk, Reset, Data, Enable, Initialize, Crc, CrcError); |
|
input Clk; |
input Reset; |
input [3:0] Data; |
input Enable; //should be valid from the destination address until the data before the CRC checksum |
input Initialize; //need to initialize before data in |
|
output [31:0] Crc; |
output CrcError; |
|
reg [31:0] Crc; |
|
wire [31:0] CrcNext; |
|
|
assign CrcNext[0] = Enable & (Data[0] ^ Crc[28]); |
assign CrcNext[1] = Enable & (Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29]); |
assign CrcNext[2] = Enable & (Data[2] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[30]); |
assign CrcNext[3] = Enable & (Data[3] ^ Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30] ^ Crc[31]); |
assign CrcNext[4] = (Enable & (Data[3] ^ Data[2] ^ Data[0] ^ Crc[28] ^ Crc[30] ^ Crc[31])) ^ Crc[0]; |
assign CrcNext[5] = (Enable & (Data[3] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[31])) ^ Crc[1]; |
assign CrcNext[6] = (Enable & (Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30])) ^ Crc[ 2]; |
assign CrcNext[7] = (Enable & (Data[3] ^ Data[2] ^ Data[0] ^ Crc[28] ^ Crc[30] ^ Crc[31])) ^ Crc[3]; |
assign CrcNext[8] = (Enable & (Data[3] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[31])) ^ Crc[4]; |
assign CrcNext[9] = (Enable & (Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30])) ^ Crc[5]; |
assign CrcNext[10] = (Enable & (Data[3] ^ Data[2] ^ Data[0] ^ Crc[28] ^ Crc[30] ^ Crc[31])) ^ Crc[6]; |
assign CrcNext[11] = (Enable & (Data[3] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[31])) ^ Crc[7]; |
assign CrcNext[12] = (Enable & (Data[2] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[30])) ^ Crc[8]; |
assign CrcNext[13] = (Enable & (Data[3] ^ Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30] ^ Crc[31])) ^ Crc[9]; |
assign CrcNext[14] = (Enable & (Data[3] ^ Data[2] ^ Crc[30] ^ Crc[31])) ^ Crc[10]; |
assign CrcNext[15] = (Enable & (Data[3] ^ Crc[31])) ^ Crc[11]; |
assign CrcNext[16] = (Enable & (Data[0] ^ Crc[28])) ^ Crc[12]; |
assign CrcNext[17] = (Enable & (Data[1] ^ Crc[29])) ^ Crc[13]; |
assign CrcNext[18] = (Enable & (Data[2] ^ Crc[30])) ^ Crc[14]; |
assign CrcNext[19] = (Enable & (Data[3] ^ Crc[31])) ^ Crc[15]; |
assign CrcNext[20] = Crc[16]; |
assign CrcNext[21] = Crc[17]; |
assign CrcNext[22] = (Enable & (Data[0] ^ Crc[28])) ^ Crc[18]; |
assign CrcNext[23] = (Enable & (Data[1] ^ Data[0] ^ Crc[29] ^ Crc[28])) ^ Crc[19]; |
assign CrcNext[24] = (Enable & (Data[2] ^ Data[1] ^ Crc[30] ^ Crc[29])) ^ Crc[20]; |
assign CrcNext[25] = (Enable & (Data[3] ^ Data[2] ^ Crc[31] ^ Crc[30])) ^ Crc[21]; |
assign CrcNext[26] = (Enable & (Data[3] ^ Data[0] ^ Crc[31] ^ Crc[28])) ^ Crc[22]; |
assign CrcNext[27] = (Enable & (Data[1] ^ Crc[29])) ^ Crc[23]; |
assign CrcNext[28] = (Enable & (Data[2] ^ Crc[30])) ^ Crc[24]; |
assign CrcNext[29] = (Enable & (Data[3] ^ Crc[31])) ^ Crc[25]; |
assign CrcNext[30] = Crc[26]; |
assign CrcNext[31] = Crc[27]; |
|
|
always @ (posedge Clk or posedge Reset) |
begin |
if (Reset) |
Crc <= 32'hffffffff; |
else |
if(Initialize) |
Crc <= 32'hffffffff; |
else |
Crc <= CrcNext; |
end |
|
assign CrcError = Crc[31:0] != 32'hc704dd7b; // CRC not equal to magic number |
|
endmodule |
/10_100m_ethernet-fifo_convertor/verilog/tri_state.v
0,0 → 1,12
//author :gurenliang |
//Email: gurenliang@gmail.com |
//note: if there are some errors, you are welcome to contact me. It would be the best appreciation to me. |
|
module tri_state(d_in, d_out, out_en, ioport); |
input d_out, out_en; //init_clk should be 10KHz |
output d_in; |
inout ioport; |
|
assign ioport = (out_en) ? d_out:1'bz; |
assign d_in = ioport; |
endmodule |
/10_100m_ethernet-fifo_convertor/verilog/RxModule.v
0,0 → 1,283
//author :Renliang Gu |
//Email: gurenliang@gmail.com |
//note: if there are some errors, please feel free to contact me. Thank you very much! |
|
//Next step, reduce the resource consumed |
|
//version 0.5, defined many parameter to configure the IP core, making it easier to use. |
//vertion 0.4, add the function for TxModule to get start in a configurable ff_clk time after |
// RxModule receiving the first frame. To modify the delay time just to |
// change the value of the macro-variable delay_cnt_config. |
//version 0.3, changed the changes made by version 0.2 back |
//version 0.2, set empty when ff_data_buf_index's less significant bits is 3'b111 or 3'b000 |
|
`include "common.v" |
|
`define IDXlen 3 //2^IDXlen should be the number of cyclic queue |
`define queue_len (1<<3) //define the length of the cyclic queue |
|
`define rx_crc_offset (`data_offset+(`uframelen*`num_uframe/4)) //index of first bit of crc |
`define rx_total_len (`rx_crc_offset + (4<<1)) |
`define rxdata_len (`uframelen*`num_uframe/4) |
|
`define delay_cnt_config 8 //the initiation value for the delay_cnt |
|
module RxModule(phy_rxd, phy_rxen, phy_rxclk, phy_rxer, |
ff_clk, ff_data, ff_en, |
|
`ifdef frameIDfromRx |
frameid, |
`endif |
|
start, |
test1, test2, test3, test4 |
); |
input phy_rxen, phy_rxclk, phy_rxer; //MII interface |
input [3:0] phy_rxd; |
|
input ff_clk; //270.8333KHz |
output ff_data, ff_en; |
|
`ifdef frameIDfromRx |
output[`frameidlen-1:0] frameid; |
reg[`frameidlen-1:0] frameid; |
`endif |
|
output start; //to tell TxModule that buf in RxModule needs data |
output test1, test2, test3, test4; |
reg test1, test2; |
|
parameter delay_cnt_len = (`delay_cnt_config < 2) ? 1 : (`delay_cnt_config < 4) ? 2 : |
(`delay_cnt_config < 8) ? 3 : (`delay_cnt_config < 16) ? 4 : |
(`delay_cnt_config < 32) ? 5 : (`delay_cnt_config < 64) ? 6 : |
(`delay_cnt_config < 128) ? 7 : 8; |
parameter nibble_idx_len = (`rx_total_len<= 2)? 1 : (`rx_total_len<= 4)? 2 : |
(`rx_total_len<= 8)? 3 : (`rx_total_len<= 16)? 4 : |
(`rx_total_len<= 32)? 5 : (`rx_total_len<= 64)? 6 : |
(`rx_total_len<= 128)? 7 : (`rx_total_len<= 256)? 8 : |
(`rx_total_len<= 512)? 9 : (`rx_total_len<=1024)? 10 : |
(`rx_total_len<=2048)? 11 : 12; |
parameter ff_idx_len = (`rxdata_len<= 2)? 1 : (`rxdata_len<= 4)? 2 : |
(`rxdata_len<= 8)? 3 : (`rxdata_len<= 16)? 4 : |
(`rxdata_len<= 32)? 5 : (`rxdata_len<= 64)? 6 : |
(`rxdata_len<= 128)? 7 : (`rxdata_len<= 256)? 8 : |
(`rxdata_len<= 512)? 9 : (`rxdata_len<=1024)?10 : |
(`rxdata_len<=2048)?11 : 12; |
parameter frameid_idx_len = ((`frameidlen>>2)<= 2)? 1 : ((`frameidlen>>2)<= 4)? 2 : |
((`frameidlen>>2)<= 8)? 3 : ((`frameidlen>>2)<= 16)? 4 : |
((`frameidlen>>2)<= 32)? 5 : ((`frameidlen>>2)<= 64)? 6 : |
((`frameidlen>>2)<= 64)? 7 : 8; |
parameter ff_cnt_len = (`uframelen < 2) ? 1 : (`uframelen < 4) ? 2 : |
(`uframelen < 8) ? 3 : (`uframelen < 16) ? 4 : |
(`uframelen < 32) ? 5 : (`uframelen < 64) ? 6 : |
(`uframelen < 128) ? 7 : (`uframelen < 256) ? 8 : |
(`uframelen < 512) ? 9 : (`uframelen < 1024) ? 10: |
(`uframelen < 2048) ? 11: (`uframelen < 4096) ? 12: |
(`uframelen < 8192) ? 13: 14; |
|
reg ff_data; |
reg ff_en; |
|
reg[ff_cnt_len-1:0] ff_cnt; |
reg[2:0] ff_d; |
|
reg start=1'b0; |
reg start_intra=1'b0; |
reg[delay_cnt_len-1:0] delay_cnt; |
|
reg[3:0] gap_cnt; |
reg[1:0] gap_len_ctl; |
reg[1:0] cycle; |
|
reg[3:0] rxdata_buf [0:(`rxdata_len*`queue_len+1)]; //more ram for special usage |
wire[ff_idx_len+`IDXlen-1:0] rxdata_buf_writer_address; |
reg[ff_idx_len+`IDXlen-1:0] rxdata_buf_reader_address; |
|
reg[`frameidlen-1:0] frameid_buf[0:(`queue_len-1)]; |
|
reg[nibble_idx_len-1:0] nibble_idx; |
reg[ff_idx_len-1:0] ff_idx; |
|
reg[`IDXlen-1:0] rxIDX, ffIDX; |
|
reg bad_da; |
reg queue_empty; |
|
reg[2:0] rxState = 0; |
parameter s_preamble = 0, s_address = 1, s_typelen = 2, |
s_frameid = 3, s_data = 4, s_crc = 5; |
reg[1:0] ff_state = 0; |
parameter ffs_idle = 0, ffs_transfer = 1, ffs_gap = 2; |
|
wire[47:0] mac_add; |
wire[3:0] da[0:11]; |
assign mac_add = `MAC_ADD; |
assign da[ 0] = mac_add[ 3: 0]; |
assign da[ 1] = mac_add[ 7: 4]; |
assign da[ 2] = mac_add[11: 8]; |
assign da[ 3] = mac_add[15:12]; |
assign da[ 4] = mac_add[19:16]; |
assign da[ 5] = mac_add[23:20]; |
assign da[ 6] = mac_add[27:24]; |
assign da[ 7] = mac_add[31:28]; |
assign da[ 8] = mac_add[35:32]; |
assign da[ 9] = mac_add[39:36]; |
assign da[10] = mac_add[43:40]; |
assign da[11] = mac_add[47:44]; |
|
assign test4 = start_intra; |
assign test3 = start; |
|
always@(posedge phy_rxclk)begin //control the increasing of nibble_idx; |
if(phy_rxen & ~phy_rxer) //data is valid and no error |
nibble_idx <= nibble_idx + 1; |
else |
nibble_idx <= 0; |
end |
|
always@(posedge phy_rxclk)begin |
if(phy_rxen & ~phy_rxer) |
case (rxState) |
s_preamble: |
if(nibble_idx == `da_offset-1) rxState <= s_address; |
else rxState <= s_preamble; |
|
s_address: |
if(nibble_idx == `typelen_offset-1) rxState <= s_typelen; |
else rxState <= s_address; |
|
s_typelen: |
if(nibble_idx == `frameid_offset-1) rxState <= s_frameid; |
else rxState <= s_typelen; |
|
s_frameid: |
if(nibble_idx == `data_offset-1) rxState <= s_data; |
else rxState <= s_frameid; |
|
s_data: |
if(nibble_idx == `rx_crc_offset-1) rxState <= s_crc; |
else rxState <= s_data; |
|
s_crc: |
if(nibble_idx == `rx_total_len-1) rxState <= s_preamble; |
else rxState <= s_crc; |
|
default: rxState <= rxState; |
endcase |
else |
rxState <= s_preamble; |
end |
|
assign rxdata_buf_writer_address = rxIDX*`rxdata_len + nibble_idx - `data_offset; |
|
always@(posedge phy_rxclk)begin //receive data from Ethernet including the preamble, SFD and CRC |
if(phy_rxen & ~phy_rxer) begin //data is valid and no error |
case (rxState) |
s_preamble: test1 <= ~test1; |
s_address: |
if((phy_rxd!=da[nibble_idx-`da_offset])&(nibble_idx < `sa_offset)) |
bad_da <= 1; |
|
s_frameid: begin |
if(nibble_idx==`frameid_offset) begin |
rxIDX <= phy_rxd[2:0]; |
frameid_buf[phy_rxd[2:0]][(`frameidlen-1):(`frameidlen-4)] <= phy_rxd; |
end else |
frameid_buf[rxIDX] <= {phy_rxd, frameid_buf[rxIDX][(`frameidlen-1):4]}; |
end |
|
s_data: begin |
//test2 <= ~test2; |
rxdata_buf[rxdata_buf_writer_address] <= phy_rxd; |
end |
endcase |
end else if ((nibble_idx == `rx_total_len ) & (!bad_da)) begin |
//one frame has been transfered over, the destinate address is right and then been put into the buffer |
start_intra <= 1; |
end else |
bad_da <= 0; |
end |
|
always@(negedge ff_clk) begin |
case(ff_state) |
ffs_idle: begin //wait the first frame to come |
gap_len_ctl <= 0; |
if(start_intra) ff_state <= ffs_transfer; |
else ff_state <= ffs_idle; |
end |
|
ffs_transfer: begin |
if(ff_cnt == `uframelen-1)begin //every `uframelen bit need a gap |
ff_state <= ffs_gap; |
gap_len_ctl <= gap_len_ctl + 1; |
end |
else ff_state <= ffs_transfer; |
end |
ffs_gap: begin |
if(((gap_len_ctl == 0)&(gap_cnt == 8)) | ((gap_len_ctl != 0)&(gap_cnt == 7))) |
ff_state <=ffs_transfer; |
else ff_state <= ffs_gap; |
end |
endcase |
end |
|
always@(negedge ff_clk) begin //flow the data out of the buffer |
case(ff_state) |
ffs_idle: begin |
ff_cnt <= 0; |
delay_cnt <= 0; |
cycle <= 0; |
ff_en <= 0; |
ff_idx <= 0; |
ffIDX <= rxIDX + 1; |
start <= 0; |
rxdata_buf_reader_address <= ffIDX*`rxdata_len+ff_idx; |
end |
|
ffs_transfer: begin |
`ifdef frameIDfromRx |
frameid <= frameid_buf[ffIDX]; |
`endif |
if(delay_cnt == `delay_cnt_config) start <= 1; |
delay_cnt <= delay_cnt + 1; |
gap_cnt <= 0; |
ff_cnt <= ff_cnt + 1; |
cycle <= cycle + 1; |
ff_en <= 1; |
|
if(cycle==0) begin |
{ff_d[2:0],ff_data} <= rxdata_buf[rxdata_buf_reader_address]; |
if(ff_idx == `rxdata_len-1)begin |
if(ffIDX!=rxIDX) begin |
queue_empty <= 0; |
if(queue_empty) begin |
ffIDX <= rxIDX + ((`delay_cnt_config==0)? 1:2) ; |
rxdata_buf_reader_address <= (rxIDX + ((`delay_cnt_config==0)? 1:2))*`rxdata_len; |
end |
else begin |
ffIDX <= ffIDX + 1; |
rxdata_buf_reader_address <= (ffIDX+1)*`rxdata_len; |
end |
end else begin |
rxdata_buf_reader_address <= ffIDX*`rxdata_len; |
queue_empty <= 1; |
end |
ff_idx <= 0; |
end |
else begin |
ff_idx <= ff_idx + 1; |
rxdata_buf_reader_address <= ffIDX*`rxdata_len+ff_idx+1; |
end |
end else |
{ff_d[1:0],ff_data} <= ff_d; |
end |
|
ffs_gap: begin //the 8.25 bit gap is implement by (3*8+9)/4 |
ff_en <= 0; |
ff_data <= 0; |
ff_cnt <= 0; |
gap_cnt <= gap_cnt + 1; |
end |
endcase |
end |
endmodule |
/10_100m_ethernet-fifo_convertor/verilog/concise.cpp
0,0 → 1,199
#include <stdio.h> |
#include <errno.h> |
#include <sys/ioctl.h> |
#include <net/if.h> |
#include <netpacket/packet.h> |
#include <net/ethernet.h> |
#include <netinet/in.h> |
#include <string.h> |
#include <stdlib.h> |
#include <sys/time.h> |
|
#define MAC_ADD_FPGA 0x00,0x00,0x00,0x00,0x00,0x01 |
#define MAC_ADD_PC 0x00,0x00,0x00,0x00,0x00,0x02 |
|
#define num 8 |
|
const unsigned char sndhead[]={MAC_ADD_FPGA, MAC_ADD_PC, 0x00, 0x00}; |
const unsigned char mac_fpga[]={MAC_ADD_FPGA}; |
|
void printdata(char* str, unsigned char* buf1, int size); |
|
int main(){ |
int error_cnt=0; |
int frame_cnt=1000; |
long int frame_number, fn1=0, fn2=0, fn3=0; |
|
unsigned int sndlen=14+3+((unsigned int)(148*num/8)); |
unsigned int rcvlen=14+3+((unsigned int)(156.25*num/8))+1; |
|
unsigned char sndbuf[sndlen]; //6+6+2+3+8*148 |
unsigned char rcvbuf[rcvlen]; //actually is 96 = 6+6+2+3+[4*156.25]+1 |
|
unsigned char* sndlentype = sndbuf + 12; |
unsigned char* sndframenumber = sndbuf + 14; |
unsigned char* snddata = sndbuf + 17; |
|
unsigned char* rcvlentype = rcvbuf + 12; |
unsigned char* rcvframenumber = rcvbuf + 14; |
unsigned char* rcvdata = rcvbuf + 17; |
|
unsigned char* temppoint; |
|
int mSocketFD; |
struct ifreq ifstruct; |
struct sockaddr_ll sll; |
int retval = 0; |
|
struct timeval testtime; |
long int usec2, usec1; |
|
memcpy(sndbuf, sndhead, 14); |
|
// create |
mSocketFD = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); |
if (mSocketFD < 0){ |
perror("socket()"); |
} |
|
//struct ifreq ifstruct; |
strcpy(ifstruct.ifr_name, "eth2"); |
retval = ioctl(mSocketFD, SIOCGIFINDEX, &ifstruct); |
if(retval == -1){ |
perror("RAWSocket::open(): ioctl()"); |
} |
|
//struct sockaddr_ll sll; |
memset(&sll, 0, sizeof(sll)); |
sll.sll_family = AF_PACKET; |
sll.sll_protocol = htons(ETH_P_ALL); |
sll.sll_ifindex = ifstruct.ifr_ifindex; |
|
// bind |
retval = bind(mSocketFD, (struct sockaddr *)&sll, sizeof(sll)); |
if(retval == -1) |
{ |
perror("RAWSocket::open(): bind()"); |
} |
|
// set recive buffer size |
//int rcvbuflen = BUFFER_SIZE; |
int rcvbuflen = 4000;//442;//221; |
retval = setsockopt(mSocketFD, SOL_SOCKET, SO_RCVBUF, (char *)&rcvbuflen, sizeof(int)); |
if (retval == -1) |
{ |
perror("RAWSocket::read(): setsockopt()"); |
} |
// set send buffer size |
//int sndbuflen = BUFFER_SIZE; |
int sndbuflen = 15000; |
retval = setsockopt(mSocketFD, SOL_SOCKET, SO_SNDBUF, (char *)&sndbuflen, sizeof(int)); |
if (retval == -1) |
{ |
perror("RAWSocket::read(): setsockopt()"); |
} |
|
frame_number = 0; |
sndframenumber[0] = frame_number; |
sndframenumber[1] = frame_number >> 8; |
sndframenumber[2] = frame_number >> 16; |
|
temppoint=snddata; |
for(int i=0; i< sndlen-17; i++){ |
if(frame_number%2==0) |
*temppoint=0;//((((unsigned char)frame_number)&0x07)<<4)|(((unsigned char)frame_number)&0x07); |
else |
*temppoint= 0xff; |
temppoint++; |
} |
|
retval = send(mSocketFD, sndbuf, sndlen, 0); |
if (retval < 0) |
{ |
perror("sendto()"); |
} |
|
while( (frame_cnt>=0)&&( (retval = recv(mSocketFD, (void*)rcvbuf, rcvlen, 0)) >=0) ) { |
|
//printf("received data length: %d\n", retval); |
|
if (retval < 42){ |
perror("recvfrom():"); |
break; |
} |
|
|
fn3 = fn2; fn2 = fn1; |
fn1 = (long int)(rcvbuf[16]<<16) + (rcvbuf[15]<<8) + rcvbuf[14]; |
long int temp; |
|
|
frame_number ++; frame_cnt--; |
sndframenumber[0] = frame_number; |
sndframenumber[1] = frame_number >> 8; |
sndframenumber[2] = frame_number >> 16; |
|
if (memcmp(mac_fpga, rcvbuf+6, 6) == 0) |
{ |
gettimeofday(&testtime, NULL); |
usec2=usec1; |
usec1=testtime.tv_usec; |
|
temp=(usec1+1000000-usec2)%1000000; |
printf("%5ld\t%5ld\t%5ld\t%x", temp, fn2, fn1, fn1&0x07); |
|
if( fn2+1 != fn1){ |
printf("\t%5ld\t*\n",frame_number); |
error_cnt++; |
}else printf("\t%5ld\n", frame_number); |
|
printdata(NULL, rcvbuf,rcvlen); |
|
temppoint=snddata; |
for(int i=0; i< sndlen-17; i++){ |
if(frame_number%2==0) |
*temppoint=0;//((((unsigned char)frame_number)&0x07)<<4)|(((unsigned char)frame_number)&0x07); |
else |
*temppoint= 0xff; |
temppoint++; |
} |
|
retval = send(mSocketFD, sndbuf, sndlen, 0); |
if (retval < 0) perror("sendto()"); |
} |
|
} |
printf("the total number of wrong frames is:%d\n", error_cnt); |
} |
|
|
void printdata(char* str, unsigned char* buf1, int size) |
{ |
unsigned char temp=0; |
unsigned int i; |
unsigned char* buf=buf1; |
|
i=0; |
printf("%s:\n",str); |
if(size==0){ |
printf("\t\tNot data!\n"); |
}else{ |
printf("\t\t"); |
while((size>0)&&(i<512)) |
{ |
printf(" %02x",*buf); |
temp++; size--; buf++; i++; |
if(!(temp & 3)) |
{ |
if(temp==16) |
{ |
temp=0; |
printf("\n\t\t"); |
}else |
printf(" "); |
} |
} |
printf("\n"); |
} |
} |
|
/10_100m_ethernet-fifo_convertor/verilog/TxModule.v
0,0 → 1,263
//author :Renliang Gu |
//Email: gurenliang@gmail.com |
//note: if there are some errors, please feel free to contact me. Thank you very much! |
|
|
//Next step, add ff_data control to show the IP is busy |
|
//version 0.3, declared a new variable data_av, and use it to start sending frame. |
//version 0.3, delete the usage of pre_buf, and rename the pre to preaddlt |
//version 0.3, add the option of frameID mode, by include common.v and judge the macro-varible frameIDfromRx |
//This module is used to receive data from the demodulate module and send the data to the Ethernet PHY chip |
|
`include "common.v" |
|
`define tx_crc_offset (`data_offset+((`uframelen+8)*`num_uframe/4)+2) //index of first bit of crc |
`define tx_total_len (`tx_crc_offset + (4<<1)) |
|
`define txdata_len (((`uframelen+8)*`num_uframe/4)+2) |
`define less_than_a_nibble 1 //0.25*8=2 |
`define last_cycle_val 2 //0.25*8=2 |
|
`define preaddlt_len (`data_offset<<2) |
|
module TxModule(reset, phy_txd, phy_txen, phy_txclk, phy_txer, |
ff_clk, ff_en, ff_data, |
|
`ifdef frameIDfromRx |
frameid, |
`endif |
|
start, |
test1, test2, test3, test4); |
parameter nibble_idx_len = (`tx_total_len<= 2)? 1 : (`tx_total_len<= 4)? 2 : |
(`tx_total_len<= 8)? 3 : (`tx_total_len<= 16)? 4 : |
(`tx_total_len<= 32)? 5 : (`tx_total_len<= 64)? 6 : |
(`tx_total_len<=128)? 7 : (`tx_total_len<=256)? 8 : |
(`tx_total_len<=512)? 9 : (`tx_total_len<=1024)? 10 : |
(`tx_total_len<=2048)? 11 : 12; |
parameter ff_idx_len = (`txdata_len<= 2)? 1 : (`txdata_len<= 4)? 2 : |
(`txdata_len<= 8)? 3 : (`txdata_len<= 16)? 4 : |
(`txdata_len<= 32)? 5 : (`txdata_len<= 64)? 6 : |
(`txdata_len<=128)? 7 : (`txdata_len<=256)? 8 : |
(`txdata_len<=512)? 9 : (`txdata_len<=1024)? 10 : 11; |
|
input phy_txclk, reset; |
input ff_clk, ff_en, ff_data; //ff_clk should be 207.83333KHz |
|
`ifdef frameIDfromRx |
input[`frameidlen-1:0] frameid; //get the frameid information from RxModule |
reg[`frameidlen-1:0] frameid_buf[0:1]; |
`endif |
`ifdef frameIDcount |
reg[`frameidlen-1:0] frameid=0; |
`endif |
reg[`frameidlen-1:0] frameid_reg; |
|
input start; //decide whether should give out the "need-data" ethernet package |
output [3:0] phy_txd; //MII |
output phy_txen, phy_txer; |
|
output test1, test2, test3, test4; |
reg test1;//, test2, test3, test4; |
|
reg[3:0] phy_txd; |
reg phy_txen; |
|
reg[`preaddlt_len-1:0] preaddlt; |
|
reg[3:0] txdata_buf[0:`txdata_len*2-1]; //two buffer helps to step over different frame seamlessly |
reg[ff_idx_len:0] txdata_buf_reader_address; |
|
reg[nibble_idx_len-1:0] nibble_idx; |
wire data_av; |
|
reg Enable_Crc, Initialize_Crc; //declare the variables for the CRC module |
wire [3:0] Data_Crc; |
wire CrcError; |
wire [31:0] Crc; |
|
wire txIDX; |
reg[1:0] cycle; |
reg ffIDX, ffIDX1, ffIDX2; |
reg[ff_idx_len-1:0] ff_idx; |
reg[2:0] ff_d; |
|
// Declare state register |
reg [2:0]txState; |
parameter s_idle = 3'h0, s_preamble = 3'h1, s_address = 3'h2, s_data = 3'h3, s_crc =3'h4; |
|
assign test2 = txState[2]; |
assign test3 = txState[1]; |
assign test4 = txState[0]; |
|
always @ (posedge ff_clk) begin //receive data from demodulate module every bit one by one |
if(ff_en & start) begin |
`ifdef frameIDfromRx |
if((ff_idx==0)&&(cycle==0)) frameid_buf[ffIDX] <= frameid; |
`endif |
|
cycle <= cycle + 1; |
if((cycle==3)|| |
((cycle == `last_cycle_val-1)&&(ff_idx==(`txdata_len-1-`less_than_a_nibble)))) begin |
|
txdata_buf[ffIDX*`txdata_len+ff_idx] <= ({ff_data,ff_d}>>(3-cycle)); |
if (ff_idx == (`txdata_len-1-`less_than_a_nibble)) begin |
ffIDX <= ~ffIDX; |
ff_idx <= 0; |
cycle <= 0; |
//every time a frame being sent, frameID increases one |
`ifdef frameIDcount |
frameid <= frameid + 1; |
`endif |
end |
else begin |
ff_idx <= ff_idx + 1; |
end |
|
end else begin |
ff_d <= {ff_data, ff_d[2:1]}; |
end |
end |
else begin |
ff_idx <= 0; |
cycle <= 0; |
end |
end |
|
assign phy_txer = 1'b0; |
assign data_av = ffIDX1 ^ ffIDX2; |
assign txIDX = ~ffIDX; |
|
always @ (negedge phy_txclk) begin //state machine run to send out the MAC frame |
ffIDX2 <= ffIDX1; |
ffIDX1 <= ffIDX; |
end |
|
// Determine the next state |
always @ (negedge phy_txclk) begin //state machine run to send out the MAC frame |
if (reset) |
txState <= s_idle; |
else begin |
case (txState) |
s_idle: begin //wait to be trigged |
test1 <= ~test1; |
if(data_av) begin //once be trigged, prepare the data to send |
txState <= s_preamble; |
end |
else txState <= s_idle; |
end |
|
s_preamble: //send the preambles |
if(nibble_idx == `da_offset-1) |
txState <= s_address; |
else |
txState <= s_preamble; |
|
s_address: begin //send the destination address, source address and type |
if(nibble_idx== `data_offset-1) |
txState <= s_data; |
else |
txState <= s_address; |
end |
s_data: //send data to PHY, every time four bits, lower bits go first |
//test2 <= ~test2; |
if (nibble_idx == `tx_crc_offset-1) |
txState <= s_crc; |
else txState <= s_data; |
|
s_crc: |
if (nibble_idx == `tx_total_len-1) |
txState <= s_idle; |
else txState <= s_crc; |
|
default: |
txState <= s_idle; |
endcase |
end |
end |
|
always @ (negedge phy_txclk) begin //state machine run to send out the MAC frame |
if (reset) |
nibble_idx <= 0; |
else if(txState==s_idle) |
nibble_idx <= 0; |
else |
nibble_idx <= nibble_idx + 1; |
end |
|
always @ (negedge phy_txclk) begin //state machine run to send out the MAC frame |
if (reset) |
phy_txd <= 4'h0; |
else |
case (txState) |
s_idle: begin |
//already stored MAC preamble, dest address and source address from right to left. |
//decide whether should ask PC for new frame |
/*if(empty) preaddlt <= {16'h0008, `MAC_ADD, `PC_MAC_ADD, `Preamble}; |
else*/ |
`ifdef frameIDfromRx |
preaddlt <= {frameid_buf[txIDX], 16'h0000, `MAC_ADD, `PC_MAC_ADD, `Preamble}; |
`endif |
`ifdef frameIDcount |
preaddlt <= {frameid, 16'h0000, `MAC_ADD, `PC_MAC_ADD, `Preamble}; |
`endif |
end |
s_preamble: |
{preaddlt[`preaddlt_len-5:0], phy_txd} <= preaddlt; |
s_address: begin |
{preaddlt[`preaddlt_len-5:0], phy_txd} <= preaddlt; |
txdata_buf_reader_address <= (txIDX*(`txdata_len)); |
end |
s_data: begin |
txdata_buf_reader_address <= (txIDX*(`txdata_len))+nibble_idx-`data_offset+1; |
phy_txd <= txdata_buf[txdata_buf_reader_address]; |
end |
s_crc: begin |
phy_txd[3] <= ~Crc[28]; //Special, the usage of the CRC_Module |
phy_txd[2] <= ~Crc[29]; |
phy_txd[1] <= ~Crc[30]; |
phy_txd[0] <= ~Crc[31]; |
end |
default: |
phy_txd <= 4'h0; |
endcase |
end |
|
always @ (negedge phy_txclk) begin //state machine run to send out the MAC frame |
if (reset) |
phy_txen <= 1'b0; |
else if((txState==s_preamble)||(txState==s_address)||(txState==s_data)||(txState==s_crc)) |
phy_txen <= 1'b1; |
else |
phy_txen <= 1'b0; |
end |
|
always @ (negedge phy_txclk) begin //state machine run to send out the MAC frame |
if (reset) |
Initialize_Crc <= 1'b0; |
else if(txState==s_preamble) |
Initialize_Crc <= 1'b1; //prepare the CRC_Module for the following addresses |
else |
Initialize_Crc <= 1'b0; |
end |
|
always @ (negedge phy_txclk) begin //state machine run to send out the MAC frame |
if (reset) |
Enable_Crc <= 1'b0; |
else if((txState==s_address)||(txState==s_data)) |
Enable_Crc <= 1'b1; //enable the CRC_Module |
else |
Enable_Crc <= 1'b0; |
end |
|
assign Data_Crc[0] = phy_txd[3]; //input prepare for CRC_Module |
assign Data_Crc[1] = phy_txd[2]; |
assign Data_Crc[2] = phy_txd[1]; |
assign Data_Crc[3] = phy_txd[0]; |
|
// Connecting module Crc |
CRC_Module txcrc (.Clk(phy_txclk), .Reset(reset), .Data(Data_Crc), .Enable(Enable_Crc), .Initialize(Initialize_Crc), |
.Crc(Crc), .CrcError(CrcError)); |
|
endmodule |
/10_100m_ethernet-fifo_convertor/verilog/test_feedback.v
0,0 → 1,45
//author :Renliang Gu |
//Email: gurenliang@gmail.com |
//note: if there are some errors, please feel free to contact me. Thank you very much! |
|
//version 0.4, the test_feedback is created, main task is to test the top module, EthernetModule.v |
// the ff_data_source is feed back to ff_data_sink |
|
module test_feedback(reset, clk_in, |
phy_rxd, phy_rxen, phy_rxclk, phy_rxer, |
phy_txd, phy_txen, phy_txclk, phy_txer, |
phy_reset, phy_col, phy_linksts, phy_crs, |
test1, test2, test3, test4 |
); |
input reset, clk_in; |
output phy_reset, test1, test2, test3, test4; |
|
input[3:0] phy_rxd; //MII interface for the phy chip |
input phy_rxclk, phy_rxer; |
|
output[3:0] phy_txd; |
output phy_txer, phy_txen; |
|
//declare them as inout port because when powerup reset, they act as output pins to config DM9161 |
//after reset, phy_txclk and phy_rxen must be input ports |
inout phy_txclk, phy_col, phy_rxen, phy_linksts, phy_crs; |
|
wire ff_en, ff_data; |
wire clk_10K, ff_clk; |
|
EthernetModule EthernetModule_inst(.reset(reset), .clk_10K(clk_10K), |
.ff_clk(ff_clk), .ff_en_source(ff_en), .ff_en_sink(1'b1), |
.ff_data_source(ff_data), .ff_data_sink(ff_data), //ff_clk should be a 270.33KHz clock |
.phy_rxd(phy_rxd), .phy_rxen(phy_rxen), .phy_rxclk(phy_rxclk), .phy_rxer(phy_rxer), |
.phy_txd(phy_txd), .phy_txen(phy_txen), .phy_txclk(phy_txclk), .phy_txer(phy_txer), |
.phy_reset(phy_reset), .phy_col(phy_col), .phy_linksts(phy_linksts), .phy_crs(phy_crs), |
.test1(test1), .test2(test2), .test3(test3), .test4(test4) |
); |
|
pll pll_inst ( |
.inclk0 ( clk_in ), |
.c0 ( clk_10K ), |
.c1 ( ff_clk ) |
); |
|
endmodule |
/10_100m_ethernet-fifo_convertor/verilog/EthernetModule.v
0,0 → 1,70
//author :gurenliang |
//Email: gurenliang@gmail.com |
//note: if there are some errors, you are welcome to contact me. It would be the best appreciation to me. |
|
|
//version 0.3 correct some minor errors |
//version 0.3 add the option of frameID mode, by include common.v and judge the macro-varible frameIDfromRx |
//The top layer module provided full functions |
`include "common.v" |
|
module EthernetModule(reset, clk_10K, |
ff_clk, ff_en_source, ff_en_sink, ff_data_source, ff_data_sink, //ff_clk should be a 270.33KHz clock |
phy_rxd, phy_rxen, phy_rxclk, phy_rxer, |
phy_txd, phy_txen, phy_txclk, phy_txer, |
phy_reset, phy_col, phy_linksts, phy_crs, |
test1, test2, test3, test4 |
); |
input reset, clk_10K, ff_clk; |
output phy_reset, test1, test2, test3, test4; |
|
input ff_en_sink, ff_data_sink; //sink is used to receive data from the demodulate module |
output ff_en_source, ff_data_source;//source is used to provide the modulation module with data get from ethernet |
|
input[3:0] phy_rxd; //MII interface for the phy chip |
input phy_rxclk, phy_rxer; |
|
output[3:0] phy_txd; |
output phy_txer, phy_txen; |
|
//declare them as inout port because when powerup reset, they act as output pins to config DM9161 |
//after reset, phy_txclk and phy_rxen must be input ports |
inout phy_txclk, phy_col, phy_rxen, phy_linksts, phy_crs; |
|
wire out_en; |
wire rxen_in, txclk_in; |
|
`ifdef frameIDfromRx |
wire[23:0] frameid; //share the frameid between TxModule and RxModule |
`endif |
|
wire empty, start; |
|
InitModule initModule_inst(.init_clk(clk_10K), .reset(reset), .phy_reset(phy_reset), .out_en(out_en)); |
|
tri_state tri_state_inst1(.d_in(txclk_in ), .d_out(1'b0), .out_en(out_en), .ioport(phy_txclk)); |
tri_state tri_state_inst2(.d_in( ), .d_out(1'b0), .out_en(out_en), .ioport(phy_col)); |
tri_state tri_state_inst3(.d_in(rxen_in ), .d_out(1'b0), .out_en(out_en), .ioport(phy_rxen)); |
tri_state tri_state_inst4(.d_in( ), .d_out(1'b0), .out_en(out_en), .ioport(phy_linksts)); |
tri_state tri_state_inst5(.d_in( ), .d_out(1'b1), .out_en(out_en), .ioport(phy_crs)); |
|
TxModule TxModule_inst(.reset(out_en), |
.phy_txd(phy_txd), .phy_txen(phy_txen), .phy_txclk(txclk_in), .phy_txer(phy_txer), |
.ff_clk(ff_clk), .ff_en(ff_en_sink), .ff_data(ff_data_sink), |
`ifdef frameIDfromRx |
.frameid(frameid), |
`endif |
.start(start), |
.test1(), .test2(), .test3(), .test4()); |
//.test1(test1), .test2(test2), .test3(test3), .test4(test4)); |
|
RxModule RxModule_inst(.phy_rxd(phy_rxd), .phy_rxen(rxen_in), .phy_rxclk(phy_rxclk), .phy_rxer(phy_rxer), |
.ff_clk(ff_clk), .ff_data(ff_data_source), .ff_en(ff_en_source), |
`ifdef frameIDfromRx |
.frameid(frameid), |
`endif |
.start(start), |
//.test1(), .test2(), .test3(), .test4()); |
.test1(test1), .test2(test2), .test3(test3), .test4(test4)); |
|
endmodule |
/10_100m_ethernet-fifo_convertor/verilog/Ethernet.fit.summary
0,0 → 1,16
Fitter Status : Successful - Sun Dec 13 21:49:10 2009 |
Quartus II Version : 9.0 Build 132 02/25/2009 SJ Full Version |
Revision Name : Ethernet |
Top-level Entity Name : test_feedback |
Family : Cyclone III |
Device : EP3C40Q240C8 |
Timing Models : Final |
Total logic elements : 1,026 / 39,600 ( 3 % ) |
Total combinational functions : 879 / 39,600 ( 2 % ) |
Dedicated logic registers : 622 / 39,600 ( 2 % ) |
Total registers : 622 |
Total pins : 24 / 129 ( 19 % ) |
Total virtual pins : 0 |
Total memory bits : 11,992 / 1,161,216 ( 1 % ) |
Embedded Multiplier 9-bit elements : 0 / 252 ( 0 % ) |
Total PLLs : 1 / 4 ( 25 % ) |
/10_100m_ethernet-fifo_convertor/verilog/common.v
0,0 → 1,31
//author :Renliang Gu |
//Email: gurenliang@gmail.com |
//note: if there are some errors, please feel free to contact me. Thank you very much! |
|
//Next step, reduce the resource consumed |
|
//version 0.5, defined many parameter to configure the IP core, making it easier to use. |
//version 0.3, create this file to be a common included one for future use to config the IP core |
//This file used to define some macro-varibles which can be used by all other files |
|
//NOTE!!! Olny one of the following two definitions can be open |
`define frameIDfromRx //frameID comes from Rxmodule |
//`define frameIDcount //frameID counts for itself by adding one every frame |
|
`define Preamble 64'hd555_5555_5555_5555 |
|
//The MAC address of this MAC IP core and the other terminal on the Ethernet, can be changed! |
`define MAC_ADD 48'h0100_0000_0000 //mac address: 0x00-00-00-00-00-01 |
`define PC_MAC_ADD 48'hffff_ffff_ffff //mac address of the other terminal |
|
`define frameidlen 24 //the id of the MAC frame |
`define uframelen 148 //148-bit |
`define num_uframe 8 //the number of uframes received once |
`define interval 8.25 //the interval between frames without send any data on fifo |
|
`define da_offset (8<<1) //8 byte before |
`define sa_offset (`da_offset+(6<<1)) //8+6 bytes before |
`define typelen_offset (`sa_offset+(6<<1)) |
`define frameid_offset (`typelen_offset+(2<<1))//index of first bit of frameid |
`define data_offset (`frameid_offset+(`frameidlen>>2)) |
//index of first bit of data |
/10_100m_ethernet-fifo_convertor/verilog/InitModule.v
0,0 → 1,28
//author :gurenliang |
//Email: gurenliang@gmail.com |
//note: if there are some errors, you are welcome to contact me. It would be the best appreciation to me. |
|
//This module incharge of the generation of the reset signal for PHY chip |
//and hold low for at least 10ms. |
module InitModule(init_clk, reset, phy_reset, out_en); |
input init_clk, reset; //init_clk should be 10KHz |
output phy_reset, out_en; |
|
reg [6:0] init_cnt=7'h0; |
reg phy_reset=1'b1; |
|
assign out_en = (init_cnt<7'h75) ? 1'b1:1'b0; |
|
always @ (posedge init_clk or posedge reset) begin |
if(reset) |
init_cnt <= 7'h0; |
else if (init_cnt <7'h7f) begin |
init_cnt <= init_cnt+7'h1; |
case (init_cnt) |
7'h02: phy_reset <= 1'b0; |
7'h66: phy_reset <= 1'b1; |
default:phy_reset <= phy_reset; |
endcase |
end |
end |
endmodule |
/10_100m_ethernet-fifo_convertor/verilog/Readme_important!!!!!.txt
0,0 → 1,12
|
Hi, everyone, |
I am sorry these days because for having no time to update the document for a few times. Here I can provide the test cpp program, concise.cpp, by connecting the fifo_source and fifo_sink. In the environment of Linux, run "g++ -o main concise.cpp" and then "./main". When the program is running, then I must be able to know how to operate the IP core. |
|
Although the document you downloaded is out of date, it can tell out some clue on how to design ethernet-fifo convertor. Now both the RxModule and TxModule are designed with RAM, so that it consume lesser resource. |
|
This project has been tested on the hardware designed by myself. I have provide the circuit in the appendix of the document. You can use it directly. If you find something wrong with the codes or have any problem on the codes, please feel free to contact me. |
|
Sincerely yours, |
Renliang Gu |
gurenliang@gmail.com |
13 Dec. 2009 |