URL
https://opencores.org/ocsvn/ha1588/ha1588/trunk
Subversion Repositories ha1588
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 38 to Rev 39
- ↔ Reverse comparison
Rev 38 → Rev 39
/ha1588/trunk/rtl/top/ha1588.v
21,6 → 21,8
|
`timescale 1ns/1ns |
|
// TODO: add define to generate rtc only or tsu only. |
|
module ha1588 ( |
input rst,clk, |
input wr_in,rd_in, |
35,6 → 37,7
input rx_gmii_clk, |
input rx_gmii_ctrl, |
input [7:0] rx_gmii_data, |
|
input tx_gmii_clk, |
input tx_gmii_ctrl, |
input [7:0] tx_gmii_data |
/ha1588/trunk/rtl/rtc/rtc.v
24,14 → 24,14
module rtc ( |
input rst, clk, |
// 1. direct time adjustment: ToD set up |
input time_ld, |
input time_ld, |
input [37:0] time_reg_ns_in, // 37:8 ns, 7:0 ns_fraction |
input [47:0] time_reg_sec_in, // 47:0 sec |
// 2. frequency adjustment: frequency set up for drift compensation |
input period_ld, |
input period_ld, |
input [39:0] period_in, // 39:32 ns, 31:0 ns_fraction |
// 3. precise time adjustment: small time difference adjustment with a time mark |
input adj_ld, |
input adj_ld, |
input [31:0] adj_ld_data, |
output reg adj_ld_done, |
input [39:0] period_adj, // 39:32 ns, 31:0 ns_fraction |
/ha1588/trunk/rtl/tsu/tsu.v
67,7 → 67,7
end |
|
// ptp CDC time stamping |
wire ts_req = int_gmii_ctrl; |
wire ts_req = int_gmii_ctrl; // TODO: check frame start delimiter |
reg ts_req_d1, ts_req_d2, ts_req_d3; |
always @(posedge rst or posedge rtc_timer_clk) begin |
if (rst) begin |
/ha1588/trunk/rtl/reg/reg.v
126,30 → 126,30
reg [31:0] reg_04; // null |
reg [31:0] reg_08; // null |
reg [31:0] reg_0c; // null |
reg [31:0] reg_10; // time 16 s |
reg [31:0] reg_14; // time 32 s |
reg [31:0] reg_18; // time 30 ns |
reg [31:0] reg_1c; // time 8 nsf |
reg [31:0] reg_20; // peri 8 ns |
reg [31:0] reg_24; // peri 32 nsf |
reg [31:0] reg_28; // ajpr 8 ns |
reg [31:0] reg_2c; // ajpr 32 nsf |
reg [31:0] reg_10; // time 16 bit s |
reg [31:0] reg_14; // time 32 bit s |
reg [31:0] reg_18; // time 30 bit ns |
reg [31:0] reg_1c; // time 8 bit nsf |
reg [31:0] reg_20; // peri 8 bit ns |
reg [31:0] reg_24; // peri 32 bit nsf |
reg [31:0] reg_28; // ajpr 8 bit ns |
reg [31:0] reg_2c; // ajpr 32 bit nsf |
reg [31:0] reg_30; // ajld 32 bit |
reg [31:0] reg_34; // null |
reg [31:0] reg_38; // null |
reg [31:0] reg_3c; // null |
reg [31:0] reg_40; // ctrl 4 bit |
reg [31:0] reg_40; // ctrl 2 bit |
reg [31:0] reg_44; // qsta 8 bit |
reg [31:0] reg_48; // qsta 8 bit |
reg [31:0] reg_48; // null |
reg [31:0] reg_4c; // null |
reg [31:0] reg_50; // null |
reg [31:0] reg_54; // null |
reg [31:0] reg_58; // null |
reg [31:0] reg_5c; // null |
reg [31:0] reg_60; // rxqu 32 bit |
reg [31:0] reg_64; // rxqu 32 bit |
reg [31:0] reg_68; // rxqu 32 bit |
reg [31:0] reg_6c; // rxqu 32 bit |
reg [31:0] reg_50; // rxqu 32 bit |
reg [31:0] reg_54; // rxqu 32 bit |
reg [31:0] reg_58; // rxqu 32 bit |
reg [31:0] reg_5c; // rxqu 32 bit |
reg [31:0] reg_60; // ctrl 2 bit |
reg [31:0] reg_64; // qsta 8 bit |
reg [31:0] reg_68; // null |
reg [31:0] reg_6c; // null |
reg [31:0] reg_70; // txqu 32 bit |
reg [31:0] reg_74; // txqu 32 bit |
reg [31:0] reg_78; // txqu 32 bit |
221,19 → 221,20
if (rd_in && cs_34) data_out_reg <= reg_34; |
if (rd_in && cs_38) data_out_reg <= reg_38; |
if (rd_in && cs_3c) data_out_reg <= reg_3c; |
// register mapping: TSU |
if (rd_in && cs_40) data_out_reg <= {reg_40[31: 4], reg_40[ 3], rxqu_ok, reg_40[ 1], txqu_ok}; |
// register mapping: TSU RX |
if (rd_in && cs_40) data_out_reg <= {reg_40[31: 2], reg_40[ 1], rxqu_ok}; |
if (rd_in && cs_44) data_out_reg <= {24'd0, rx_q_stat_int[ 7: 0]}; |
if (rd_in && cs_48) data_out_reg <= {24'd0, tx_q_stat_int[ 7: 0]}; |
if (rd_in && cs_48) data_out_reg <= reg_48; |
if (rd_in && cs_4c) data_out_reg <= reg_4c; |
if (rd_in && cs_50) data_out_reg <= reg_50; |
if (rd_in && cs_54) data_out_reg <= reg_54; |
if (rd_in && cs_58) data_out_reg <= reg_58; |
if (rd_in && cs_5c) data_out_reg <= reg_5c; |
if (rd_in && cs_60) data_out_reg <= rx_q_data_int[127: 96]; |
if (rd_in && cs_64) data_out_reg <= rx_q_data_int[ 95: 64]; |
if (rd_in && cs_68) data_out_reg <= rx_q_data_int[ 63: 32]; |
if (rd_in && cs_6c) data_out_reg <= rx_q_data_int[ 31: 0]; |
if (rd_in && cs_50) data_out_reg <= rx_q_data_int[127: 96]; |
if (rd_in && cs_54) data_out_reg <= rx_q_data_int[ 95: 64]; |
if (rd_in && cs_58) data_out_reg <= rx_q_data_int[ 63: 32]; |
if (rd_in && cs_5c) data_out_reg <= rx_q_data_int[ 31: 0]; |
// register mapping: TSU TX |
if (rd_in && cs_60) data_out_reg <= {reg_60[31: 2], reg_60[ 1], txqu_ok}; |
if (rd_in && cs_64) data_out_reg <= {24'd0, tx_q_stat_int[ 7: 0]}; |
if (rd_in && cs_68) data_out_reg <= reg_68; |
if (rd_in && cs_6c) data_out_reg <= reg_6c; |
if (rd_in && cs_70) data_out_reg <= tx_q_data_int[127: 96]; |
if (rd_in && cs_74) data_out_reg <= tx_q_data_int[ 95: 64]; |
if (rd_in && cs_78) data_out_reg <= tx_q_data_int[ 63: 32]; |
256,15 → 257,26
assign period_adj_out [39:0] = {reg_28[ 7: 0], reg_2c[31: 0]}; |
assign adj_ld_data_out [31:0] = reg_30[31: 0]; |
|
// register mapping: TSU |
// register mapping: TSU RX |
//wire = reg_40[ 7]; |
//wire = reg_40[ 6]; |
//wire = reg_40[ 5]; |
//wire = reg_40[ 4]; |
wire rxq_rst = reg_40[ 3]; |
wire rxqu_rd = reg_40[ 2]; |
wire txq_rst = reg_40[ 1]; |
wire txqu_rd = reg_40[ 0]; |
//wire = reg_40[ 3]; |
//wire = reg_40[ 2]; |
wire rxq_rst = reg_40[ 1]; |
wire rxqu_rd = reg_40[ 0]; |
|
// register mapping: TSU TX |
//wire = reg_60[ 7]; |
//wire = reg_60[ 6]; |
//wire = reg_60[ 5]; |
//wire = reg_60[ 4]; |
//wire = reg_60[ 3]; |
//wire = reg_60[ 2]; |
wire txq_rst = reg_60[ 1]; |
wire txqu_rd = reg_60[ 0]; |
// TODO: add configurable PTP Event msgID value mask |
// TODO: add configurable VLANTPID values |
|
// real time clock |
/ha1588/trunk/doc/DESCRIPTION.txt
0,0 → 1,36
General Description |
|
Hardware Assisted IEEE 1588 IP Core. The necessary FPGA logic to assist SW protocol stack in implementing the Precision Time Protocol (IEEE 1588-2008) on 1000M/100M/10M Ethernet networks. PTP packet transmitting and receiving is implemented with any existing MAC inside or outside the FPAG; The IP Core will implement the tunable Real-Time Clock and Time Stamping of PTP event packets (L2, UDP/IPv4/MPLS/VLAN and UDP/IPv6/MPLS/VLAN) in two-step-mode. |
|
Feature Description |
|
RTC: Real Time Clock. |
* Standard PTP clock output with 2^48s and 2^32ns time resolution. |
* Tunable accumulator based clock with 2^-8ns time resolution and 2^-32ns period resolution. |
** Direct ToD write, with 2^-8ns resolution. |
** Direct frequency write, with 2^-32ns resolution. |
** Timed temporary time adjustment, with 2^-8ns resolution and 2^32bit timer. |
* Clock Domain Crossing hand-shaking, for SW read and write accesses. |
|
TSU: Time Stamping Unit. |
* Two-Step PTP operation. |
* 15-entry timestamp queue. |
* 128bit timestamp format. |
** 16bit extra information. |
** 80bit timestamp. |
** 32bit packet identity data. |
* GMII interface tap with line-speed PTP event packet parsing. |
** Sync |
** Delay_Req |
** Pdelay_Req |
** Pdelay_Resp |
* Variety of PTP packet formats support. |
** L2 PTP packet with stacked VLAN tags. |
** IPv4 and IPv6 UDP PTP packet with stacked VLAN tags and stacked MPLS labels. |
* 32bit internal datapath for easier timing closure. |
|
SystemVerilog DPI based simulation environment is included for SW driver development. |
|
The IP Core can be used as an IP Component in Altera SOPC Builder. |
|
The only FPGA vendor dependent module is the timestamp queue. This Altera DCFIFO can be replaced by other FPGA vendor specific dual clock FIFO. |
/ha1588/trunk/doc/RTC MEMORY MAP.csv
0,0 → 1,48
|
|
REG NAME, REG ADDR, BIT, NAME, R/W, DESCRIPTION, DEFAULT, |
|
RTC_CTRL, 0x00000000, 31: 5, NULL, R/W, , 0, |
, , 4, RTC_SET_RESET, R/W, , 0, |
, , 3, RTC_SET_TIME, R/W, , 0, |
, , 2, RTC_SET_PERIOD, R/W, , 0, |
, , 1, RTC_SET_ADJ, R/W, , 0, |
, , 0, RTC_GET_TIME, R/W, , 0, |
|
RTC_NULL_0x04, 0x00000004, 31: 0, NULL, R/W, , 0, |
|
RTC_NULL_0x08, 0x00000008, 31: 0, NULL, R/W, , 0, |
|
RTC_NULL_0x0C, 0x0000000C, 31: 0, NULL, R/W, , 0, |
|
RTC_TIME_SEC_H, 0x00000010, 31:16, NULL, R/W, , 0, |
, , 15: 0, RTC_TIME_SEC_47_32, R/W, , 0, |
|
RTC_TIME_SEC_L, 0x00000014, 31: 0, RTC_TIME_SEC_31_00, R/W, , 0, |
|
RTC_TIME_NSC_H, 0x00000018, 31:30, NULL, R/W, , 0, |
, , 29: 0, RTC_TIME_NSC_29_00, R/W, , 0, |
|
RTC_TIME_NSC_L, 0x0000001C, 31: 8, NULL, R/W, , 0, |
, , 7: 0, RTC_TIME_SUB_NSC_07_00, R/W, , 0, |
|
RTC_PERIOD_H, 0x00000020, 31: 8, NULL, R/W, , 0, |
, , 7: 0, RTC_PERIOD_NSC_07_00, R/W, , 0, |
|
RTC_PERIOD_L, 0x00000024, 31: 0, RTC_PERIOD_SUB_NSC_31_00, R/W, , 0, |
|
RTC_ADJPER_H, 0x00000028, 31: 8, NULL, R/W, , 0, |
, , 7: 0, RTC_ADJPER_NSC_07_00, R/W, , 0, |
|
RTC_ADJPER_L, 0x0000002C, 31: 0, RTC_ADJPER_SUB_NSC_31_00, R/W, , 0, |
|
RTC_ADJNUM, 0x00000030, 31: 0, RTC_ADJNUM_CNT_31_00, R/W, , 0, |
|
RTC_NULL_0x34, 0x00000034, 31: 0, NULL, R/W, , 0, |
|
RTC_NULL_0x38, 0x00000038, 31: 0, NULL, R/W, , 0, |
|
RTC_NULL_0x3C, 0x0000003C, 31: 0, NULL, R/W, , 0, |
|
|
|
/ha1588/trunk/doc/TSU MEMORY MAP.csv
0,0 → 1,52
|
|
REG NAME, REG ADDR, BIT, NAME, R/W, DESCRIPTION, DEFAULT, |
|
TSU_RXCTRL, 0x00000040, 31: 2, NULL, R/W, , 0, |
, , 1, TSU_SET_RXRST, R/W, , 0, |
, , 0, TSU_GET_RXQUE, R/W, , 0, |
|
TSU_RXQUE_STATUS, 0x00000044, 31: 8, NULL, R/W, , 0, |
, , 7: 0, TSU_RXQUE_NUMBER, R/W, , 0, |
|
TSU_NULL_0x48, 0x00000048, 31: 0, NULL, R/W, , 0, |
|
TSU_NULL_0x4C, 0x0000004C, 31: 0, NULL, R/W, , 0, |
|
TSU_RXQUE_DATA_HH, 0x00000050, 31:16, NULL, R/W, , 0, |
, , 15: 0, TSU_RXQUE_SEC_47_32, R/W, , 0, |
|
TSU_RXQUE_DATA_HL, 0x00000054, 31: 0, TSU_RXQUE_SEC_31_00, R/W, , 0, |
|
TSU_RXQUE_DATA_LH, 0x00000058, 31:30, NULL, R/W, , 0, |
, , 29: 0, TSU_RXQUE_NSC_29_00, R/W, , 0, |
|
TSU_RXQUE_DATA_LL, 0x0000005C, 31:28, TSU_RXQUE_PTP_MSG_ID, R/W, , 0, |
, , 27:16, TSU_RXQUE_PTP_CK_SUM, R/W, , 0, |
, , 15: 0, TSU_RXQUE_PTP_SEQ_ID, R/W, , 0, |
|
TSU_TXCTRL, 0x00000060, 31: 2, NULL, R/W, , 0, |
, , 1, TSU_SET_TXRST, R/W, , 0, |
, , 0, TSU_GET_TXQUE, R/W, , 0, |
|
TSU_TXQUE_STATUS, 0x00000064, 31: 8, NULL, R/W, , 0, |
, , 7: 0, TSU_TXQUE_NUMBER, R/W, , 0, |
|
TSU_NULL_0x68, 0x00000068, 31: 0, NULL, R/W, , 0, |
|
TSU_NULL_0x6C, 0x0000006C, 31: 0, NULL, R/W, , 0, |
|
TSU_TXQUE_DATA_HH, 0x00000070, 31:16, NULL, R/W, , 0, |
, , 15: 0, TSU_TXQUE_SEC_47_32, R/W, , 0, |
|
TSU_TXQUE_DATA_HL, 0x00000074, 31: 0, TSU_TXQUE_SEC_31_00, R/W, , 0, |
|
TSU_TXQUE_DATA_LH, 0x00000078, 31:30, NULL, R/W, , 0, |
, , 29: 0, TSU_TXQUE_NSC_29_00, R/W, , 0, |
|
TSU_TXQUE_DATA_LL, 0x0000007C, 31:28, TSU_TXQUE_PTP_MSG_ID, R/W, , 0, |
, , 27:16, TSU_TXQUE_PTP_CK_SUM, R/W, , 0, |
, , 15: 0, TSU_TXQUE_PTP_SEQ_ID, R/W, , 0, |
|
|
|
/ha1588/trunk/sim/top/ptp_drv_bfm/ptp_drv_bfm.c
26,9 → 26,9
|
// define RTC address values |
#define RTC_CTRL 0x00000000 |
#define RTC_NULL_0x4 0x00000004 |
#define RTC_NULL_0x8 0x00000008 |
#define RTC_NULL_0xC 0x0000000C |
#define RTC_NULL_0x04 0x00000004 |
#define RTC_NULL_0x08 0x00000008 |
#define RTC_NULL_0x0C 0x0000000C |
#define RTC_TIME_SEC_H 0x00000010 |
#define RTC_TIME_SEC_L 0x00000014 |
#define RTC_TIME_NSC_H 0x00000018 |
42,32 → 42,32
#define RTC_NULL_0x38 0x00000038 |
#define RTC_NULL_0x3C 0x0000003C |
// define RTC control values |
#define RTC_SET_CTRL_0 0x00 |
#define RTC_GET_TIME 0x01 |
#define RTC_SET_ADJ 0x02 |
#define RTC_SET_PERIOD 0x04 |
#define RTC_SET_TIME 0x08 |
#define RTC_SET_RESET 0x10 |
#define RTC_SET_CTRL_0 0x00 |
#define RTC_GET_TIME 0x01 |
#define RTC_SET_ADJ 0x02 |
#define RTC_SET_PERIOD 0x04 |
#define RTC_SET_TIME 0x08 |
#define RTC_SET_RESET 0x10 |
// define RTC data values |
#define RTC_SET_PERIOD_H 0x8 // 8ns for 125MHz rtc_clk |
#define RTC_SET_PERIOD_H 0x8 // 8ns for 125MHz rtc_clk |
#define RTC_SET_PERIOD_L 0x0 |
// define RTC constant |
#define RTC_ACCMOD_H 0x3B9ACA00 // 1,000,000,000 for 30bit |
#define RTC_ACCMOD_L 0x0 // 256 for 8bit |
#define RTC_ACCMOD_H 0x3B9ACA00 // 1,000,000,000 for 30bit |
#define RTC_ACCMOD_L 0x0 // 256 for 8bit |
|
// define TSU address values |
#define TSU_CTRL 0x00000040 |
#define TSU_RXCTRL 0x00000040 |
#define TSU_RXQUE_STATUS 0x00000044 |
#define TSU_TXQUE_STATUS 0x00000048 |
#define TSU_NULL_0x48 0x00000048 |
#define TSU_NULL_0x4C 0x0000004C |
#define TSU_NULL_0x50 0x00000050 |
#define TSU_NULL_0x54 0x00000054 |
#define TSU_NULL_0x58 0x00000058 |
#define TSU_NULL_0x5C 0x0000005C |
#define TSU_RXQUE_DATA_HH 0x00000060 |
#define TSU_RXQUE_DATA_HL 0x00000064 |
#define TSU_RXQUE_DATA_LH 0x00000068 |
#define TSU_RXQUE_DATA_LL 0x0000006C |
#define TSU_RXQUE_DATA_HH 0x00000050 |
#define TSU_RXQUE_DATA_HL 0x00000054 |
#define TSU_RXQUE_DATA_LH 0x00000058 |
#define TSU_RXQUE_DATA_LL 0x0000005C |
#define TSU_TXCTRL 0x00000060 |
#define TSU_TXQUE_STATUS 0x00000064 |
#define TSU_NULL_0x68 0x00000068 |
#define TSU_NULL_0x6C 0x0000006C |
#define TSU_TXQUE_DATA_HH 0x00000070 |
#define TSU_TXQUE_DATA_HL 0x00000074 |
#define TSU_TXQUE_DATA_LH 0x00000078 |
74,10 → 74,10
#define TSU_TXQUE_DATA_LL 0x0000007C |
// define TSU control values |
#define TSU_SET_CTRL_0 0x00 |
#define TSU_GET_RXQUE 0x01 |
#define TSU_SET_RXRST 0x02 |
#define TSU_GET_TXQUE 0x01 |
#define TSU_SET_TXRST 0x02 |
#define TSU_GET_RXQUE 0x04 |
#define TSU_SET_RXRST 0x08 |
|
int ptp_drv_bfm_c(double fw_delay) |
{ |
230,14 → 230,22
int tx_queue_num; |
|
// RESET TSU |
cpu_addr_i = TSU_CTRL; |
cpu_addr_i = TSU_RXCTRL; |
cpu_data_i = TSU_SET_CTRL_0; |
cpu_wr(cpu_addr_i, cpu_data_i); |
|
cpu_addr_i = TSU_CTRL; |
cpu_data_i = TSU_SET_RXRST + TSU_SET_TXRST; |
cpu_addr_i = TSU_RXCTRL; |
cpu_data_i = TSU_SET_RXRST; |
cpu_wr(cpu_addr_i, cpu_data_i); |
|
cpu_addr_i = TSU_TXCTRL; |
cpu_data_i = TSU_SET_CTRL_0; |
cpu_wr(cpu_addr_i, cpu_data_i); |
|
cpu_addr_i = TSU_TXCTRL; |
cpu_data_i = TSU_SET_TXRST; |
cpu_wr(cpu_addr_i, cpu_data_i); |
|
// READ TSU |
while (1) { |
|
251,16 → 259,16
for (i=rx_queue_num; i>0; i--) { |
|
// READ TSU RX FIFO |
cpu_addr_i = TSU_CTRL; |
cpu_addr_i = TSU_RXCTRL; |
cpu_data_i = TSU_SET_CTRL_0; |
cpu_wr(cpu_addr_i, cpu_data_i); |
|
cpu_addr_i = TSU_CTRL; |
cpu_addr_i = TSU_RXCTRL; |
cpu_data_i = TSU_GET_RXQUE; |
cpu_wr(cpu_addr_i, cpu_data_i); |
|
do { |
cpu_addr_i = TSU_CTRL; |
cpu_addr_i = TSU_RXCTRL; |
cpu_rd(cpu_addr_i, &cpu_data_o); |
//printf("%08x\n", cpu_data_o); |
} while ((cpu_data_o & TSU_GET_RXQUE) == 0x0); |
324,16 → 332,16
for (i=tx_queue_num; i>0; i--) { |
|
// READ TSU TX FIFO |
cpu_addr_i = TSU_CTRL; |
cpu_addr_i = TSU_TXCTRL; |
cpu_data_i = TSU_SET_CTRL_0; |
cpu_wr(cpu_addr_i, cpu_data_i); |
|
cpu_addr_i = TSU_CTRL; |
cpu_addr_i = TSU_TXCTRL; |
cpu_data_i = TSU_GET_TXQUE; |
cpu_wr(cpu_addr_i, cpu_data_i); |
|
do { |
cpu_addr_i = TSU_CTRL; |
cpu_addr_i = TSU_TXCTRL; |
cpu_rd(cpu_addr_i, &cpu_data_o); |
//printf("%08x\n", cpu_data_o); |
} while ((cpu_data_o & TSU_GET_TXQUE) == 0x0); |