реклама на сайте
подробности

 
 
> Через некоторое время перестает работать проект, Машина состояний впадает в неопределенное состояние
Digi
сообщение Mar 23 2015, 14:15
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 150
Регистрация: 20-08-04
Пользователь №: 529



Вообщем возникла такая проблема и уже не пойму в какую сторону копать: Ниже код передатчика от MAC. Запускаю, некоторое время все работает, но по непонятным причинам, через несколько сотен посылок, код перестает работать. Конкретно проблема возникает в том что машина состояний state_Tx уходит в неопределенное состояние, то есть становится равной НУЛЮ (смотрел в Signal Tap). А в нормальном режиме он хоть чему нибудь должна быть равна. Еще добавил default в case , при заходе в который state_Tx должна стать равной RESET, но не помогло. Так же когда state_Tx становиться равным нулю, начинают увеличиваться rdaddress , он доходит до 0x3F и начинает с нуля. И data_count, считает до 0x3ff. Также обновляется temp_CRC32.
До этого при некоторых вариантах компиляции проекта все работало отлично. Стоит чего либо поменять, начинает работать нестабильно. Уже не знаю что может вызывать такой эффект. Может кто свежим взглядом посмотрит и направит на путь истинный. Кстати с констрейнами я плохо дружу. Попытался прописать клоки, но результат вроде как стал хуже. Теперь при различных компиляциях вообще не работает нормально (при подключеном stp и без него).
Основная проблема в том что я не могу понять, почему state_Tx становиться равным НУЛЮ ? Подскажите, в какую сторону дальше грести.

Прикрепленное изображение


------ SDC файл ----
Код
create_clock -name {altera_reserved_tck} -period 100.000 -waveform { 0.000 50.000 } [get_ports {altera_reserved_tck}]
create_clock -name {CLOCK_50} -period 20.000 -waveform { 0.000 10.000 } [get_ports {CLOCK_50}]
create_clock -name {CLOCK2_50} -period 20.000 -waveform { 0.000 10.000 } [get_ports {CLOCK2_50}]
create_clock -name {CLOCK3_50} -period 20.000 -waveform { 0.000 10.000 } [get_ports {CLOCK3_50}]
create_clock -name {PHY_RX_CLOCK} -period 8.000 -waveform { 0.000 4.000 } [get_ports { ENET0_RX_CLK }]
create_clock -name {PHY_TX_CLOCK} -period 8.000 -waveform { 0.000 4.000 } [get_ports { ENET0_TX_CLK }]       - это пин с PHY контроллера


#**************************************************************
# Create Generated Clock
#**************************************************************

create_generated_clock -name {PHY_TX_CLOCK_2} -source [get_ports {ENET0_TX_CLK}] -duty_cycle 50.000 -multiply_by 1 -divide_by 2 -master_clock {PHY_TX_CLOCK} [get_nets {gen_tx_clock_2}]


Кусок из верхнего уровня, который генерит PHY_TX_CLOCK_2


Код
GLOBAL tx_clk_inst1 (.in( !ENET0_TX_CLK ), .out(PHY_TX_CLOCK));        // Делает линию PHY_TX_CLOCK глобальной тактовой

// generate PHY_TX_CLOCK/2 for 100T
wire PHY_TX_CLOCK_2;
reg gen_tx_clock_2;
always @ (posedge PHY_TX_CLOCK) gen_tx_clock_2 <= ~gen_tx_clock_2;

GLOBAL tx_clk_inst2 (.in( gen_tx_clock_2 ), .out(PHY_TX_CLOCK_2));    // Глобальная линия для TX_CLK/2





CODE
module Tx_MAC ( Tx_clock, Tx_clock_2, IF_rst, Send_ARP,ping_reply,
PHY_Tx_data, PHY_Tx_rdused, ping_data, LED, Tx_fifo_rdreq,
Tx_CTL, ARP_sent, ping_sent, TD, DHCP_discover, DHCP_discover_sent,
This_MAC,SIADDR, DHCP_request,
DHCP_request_sent, METIS_discovery, PC_IP, PC_MAC,
Port, This_IP, METIS_discover_sent, ARP_PC_MAC, ARP_PC_IP,
Ping_PC_MAC, Ping_PC_IP, Length, speed_100T, Tx_reset, run, wide_spectrum,
IP_valid, printf, IP_lease, DHCP_IP, DHCP_MAC, DHCP_request_renew, DHCP_request_renew_sent,
erase_done, erase_done_ACK, send_more, send_more_ACK, Hermes_serialno,
sp_fifo_rddata, sp_fifo_rdreq, sp_fifo_rdempty, sp_fifo_rdused, have_sp_data,
AssignIP,
pll_data, send_pll_data, send_pll_data_ACK );



input Tx_clock; // 25MHz for 100T
input Tx_clock_2; // clock/2
input IF_rst; // reset signal
input Send_ARP; // high to send ARP response
input ping_reply; // high to send ping response
input [7:0]PHY_Tx_data; // data to send to PHY
input [10:0]PHY_Tx_rdused; // data available in Tx fifo
input [7:0]ping_data[0:59]; // data to send back
input DHCP_discover; // high when requested
input [47:0]This_MAC; // MAC address of this Metis board
input [31:0]SIADDR; // IP address of server that provided IP address
input DHCP_request; // high when request required
input METIS_discovery; // high when reply required
input [31:0]PC_IP; // IP address of the PC we are connecting to
input [47:0]PC_MAC; // MAC address of the PC we are connecting to
input [15:0]Port; // Port on the PC we are sending to
input [31:0]This_IP; // IP address provided by PC or DHCP at start up
input [47:0]ARP_PC_MAC; // MAC address of PC requesting ARP
input [31:0]ARP_PC_IP; // IP address of PC requesting ARP
input [47:0]Ping_PC_MAC; // MAC address of PC requesting ping
input [31:0]Ping_PC_IP; // IP address of PC requesting ping
input [15:0]Length; // Lenght of packet - used by ping
input speed_100T; // high for 100T,low for 1000T ************ check
input Tx_reset; // high to prevent I&Q data being sent
input run; // high to enable data to be sent
input wide_spectrum; // high to enable wide spectrum data to be sent
input IP_valid; // high when we have a valid IP address
input printf; // high when we want to send debug data
input [31:0]IP_lease; // *** test data - IP lease time in seconds
input [31:0]DHCP_IP; // IP address of DHCP server
input [47:0]DHCP_MAC; // MAC address of DHCP server
input DHCP_request_renew; // set when renew required
input erase_done; // set when we what to tell the PC we have completed the EPCS16 erase
input send_more; // set when we want the next block of 256 bytes for the EPCS16
input [7:0]Hermes_serialno; // Hermes code version
input [7:0]sp_fifo_rddata; // raw ACD data from Mercury for wide bandscope
input sp_fifo_rdempty; // SP_fifo read empty
input [12:0]sp_fifo_rdused; // SP_fifo contents
input have_sp_data; // high when sp_fifo is full.
input [31:0]AssignIP; // IP address read from EEPROM

input [7:0] pll_data [0:32]; // Массив регистров pll
input send_pll_data;
output send_pll_data_ACK;

output LED; // show MAC is doing something!
output Tx_fifo_rdreq; // high to indicate read from Tx fifo required
output Tx_CTL; // high to enable write to PHY
output ARP_sent; // high indicates ARP has been sent
output ping_sent; // high indicates ping reply has been sent
output [3:0]TD; // nibble to send to PHY
output DHCP_discover_sent; // high when has been sent
output DHCP_request_sent; // high when has been sent
output METIS_discover_sent; // high when has been sent ** pulse
output DHCP_request_renew_sent; // high when has been sent
output erase_done_ACK; // set when we have sent erase of EPCS16 complete to PC
output send_more_ACK; // set when we confirm we have requested more EPCS data from PC
output sp_fifo_rdreq; // SP_fifo read require signal



// HPSDR specific
parameter HPSDR_frame = 8'h01; // HPSDR Frame type
parameter HPSDR_IP_frame = 8'h03; // Read IP Frame type
// parameter end_point = 8'h06; // HPSDR end point - 6 to indicate fifo write
parameter Type_1 = 8'hEF; // Ethernet Frame type
parameter Type_2 = 8'hFE;
localparam TxPort = 16'd1024; // Metis 'from' port
//localparam IP_MAC = 48'h00_22_33_44_55_66; // MAC address used for setting and reading IP address

localparam
RESET = 1,
UDP = 2,
// METIS_DISCOVERY = 4,
ARP = 8,
PING1 = 16,
PING2 = 32,
// DHCP_DISCOVER = 64,
// DHCP_REQUEST = 128,
// DHCP_REQUEST_RENEW = 256,
// PRINTF = 512,
// SPECTRUM = 1024,
// SENDIP = 11,
CRC = 2048,
// TEST_PACKET = 4096,
PLL_DATA = 8192;


wire [7:0]ping_data[0:59]; // data to send back

wire [31:0] CRC32; // holds 802.3 CRC result
reg [31:0] temp_CRC32 = 0;

reg [31:0] sequence_number = 0;
reg [31:0] spec_seq_number = 0;

reg sp_fifo_rdreq;
reg DHCP_request_sent;
reg Tx_fifo_rdreq;
reg METIS_discover_sent;
reg DHCP_discover_sent;

reg [15:0] state_Tx; // state for FX2
reg [10:0] data_count;
reg [10:0] sp_data_count;
reg reset_CRC;
reg [7:0] Tx_data;
reg [4:0] gap_count;
reg ARP_sent; // true when we have replied to an ARP request
reg LED; // Test LED
reg erase_done_ACK; // set when we have sent erase of EPCS16 complete to PC
reg send_more_ACK; // set when we confirm we have requested more EPCS data from PC
reg [31:0]Discovery_IP; // IP address of PC doing Discovery
reg [47:0]Discovery_MAC; // MAC address of PC doing Discovery
reg [15:0]Discovery_Port; // Port Address of PC doing Discovery

reg [7:0]end_point; // USB end point equivalent 8'h06 for IQ data and 8'h04 for Spectrum
reg [4:0]IP_count; // holds shift count when sending IP to PHY TX fifo



wire [15:0]DHCP_length;
wire [15:0]UDP_DHCP_length;

wire [15:0]DHCP_req_length;
wire [15:0]UDP_DHCP_req_length;

wire [15:0]DHCP_req_renew_length;
wire [15:0]UDP_DHCP_req_renew_length;


reg [9:0] rdaddress;
reg [7:0] pkt_data;
reg [7:0] ck_count;
reg [31:0]ping_check_temp;
reg [15:0]ping_check_sum;
reg ping_sent;
reg [8:0] zero_count;
reg [3:0]interframe;
reg xprintf;
reg DHCP_request_renew_sent;
reg Metis_discover_sent;
reg [7:0] frame; // HPSDR frame type; 0x02 for Discovery reply,
// 0x03 for EPCS16 erase complete and
// 0x04 for send next 256 bytes for EPCS16 program
reg [31:0]temp_IP; // holds IP address from EEPROM whilst we are shifting

reg [4:0]PHY_state;
reg sync_Tx_CTL;
reg [3:0] sync_TD;


assign Reset = IF_rst; // Set reset signal to IF_rst


// calculate the IP checksum, big-endian style
// The 0xC935 is fixed and made up of the 16 bit add of the header data. *** this will need changing if we change payload size ****
// i.e. 0x4500 + 0x0424 + 0x8011 = 0xC935
// then add the IPsource and IPDesitination in 16 bits using 1's complement and then complement

// calculate the UDP/IP checksum
wire [31:0]IPchecksum1;
wire [31:0]IPchecksum2;
wire [15:0]IPchecksum3;

assign IPchecksum1 = 32'h0000C935 + This_IP[31:16] + This_IP[15:0] + PC_IP[31:16] + PC_IP[15:0];

assign IPchecksum2 = ((IPchecksum1 & 32'h0000FFFF) + (IPchecksum1 >> 16)); // 1's complement add, shift the higher order bits and add
assign IPchecksum3 = ~((IPchecksum2 & 32'h0000FFFF) + (IPchecksum2 >> 16)); // again, then complement

// calculate the UDP/IP checksum for Metis discovery
wire [31:0]DISchecksum1;
wire [31:0]DISchecksum2;
wire [15:0]DISchecksum3;

assign DISchecksum1 = 32'h00004500 + 32'h00000058 + 32'h00008011 + This_IP[31:16] + This_IP[15:0] +
Discovery_IP[31:16] + Discovery_IP[15:0];

assign DISchecksum2 = ((DISchecksum1 & 32'h0000FFFF) + (DISchecksum1 >> 16)); // 1's complement add, shift the higher order bits and add
assign DISchecksum3 = ~((DISchecksum2 & 32'h0000FFFF) + (DISchecksum2 >> 16)); // again, then complement


// calculate the IP checksum for ICMP (ping)
wire [31:0]ICMPchecksum1;
wire [31:0]ICMPchecksum2;
wire [15:0]ICMPchecksum3;

assign ICMPchecksum1 = 32'h00004500 + Length + 32'h00008001 + This_IP[31:16] + This_IP[15:0] +
Ping_PC_IP[31:16] + Ping_PC_IP[15:0];

assign ICMPchecksum2 = ((ICMPchecksum1 & 32'h0000FFFF) + (ICMPchecksum1 >> 16)); // 1's complement add, shift the higher order bits and add
assign ICMPchecksum3 = ~((ICMPchecksum2 & 32'h0000FFFF) + (ICMPchecksum2 >> 16)); // again, then complement

// calculate the IP checksum for DHCP discovery
wire [31:0]DHCPchecksum1;
wire [31:0]DHCPchecksum2;
wire [15:0]DHCPchecksum3;

assign DHCPchecksum1 = 32'h00004500 + UDP_DHCP_length + 32'h00008011 + 32'h0000FFFF + 32'h0000FFFF;

assign DHCPchecksum2 = ((DHCPchecksum1 & 32'h0000FFFF) + (DHCPchecksum1 >> 16)); // 1's complement add, shift the higher order bits and add
assign DHCPchecksum3 = ~((DHCPchecksum2 & 32'h0000FFFF) + (DHCPchecksum2 >> 16)); // again, then complement

// calculate IP checksum for DHCP request
wire [31:0]DHCP_req_checksum1;
wire [31:0]DHCP_req_checksum2;
wire [15:0]DHCP_req_checksum3;

assign DHCP_req_checksum1 = 32'h00004500 + UDP_DHCP_req_length + 32'h00008011 + 32'h0000FFFF + 32'h0000FFFF;

assign DHCP_req_checksum2 = ((DHCP_req_checksum1 & 32'h0000FFFF) + (DHCP_req_checksum1 >> 16)); // 1's complement add, shift the higher order bits and add
assign DHCP_req_checksum3 = ~((DHCP_req_checksum2 & 32'h0000FFFF) + (DHCP_req_checksum2 >> 16)); // again, then complement

// calculate IP checksum for DHCP request renew
wire [31:0]DHCP_req_renew_checksum1;
wire [31:0]DHCP_req_renew_checksum2;
wire [15:0]DHCP_req_renew_checksum3;

assign DHCP_req_renew_checksum1 = 32'h00004500 + UDP_DHCP_req_renew_length + 32'h00008011 + This_IP[31:16] + This_IP[15:0] +
DHCP_IP[31:16] + DHCP_IP[15:0];

assign DHCP_req_renew_checksum2 = ((DHCP_req_renew_checksum1 & 32'h0000FFFF) + (DHCP_req_renew_checksum1 >> 16)); // 1's complement add, shift the higher order bits and add
assign DHCP_req_renew_checksum3 = ~((DHCP_req_renew_checksum2 & 32'h0000FFFF) + (DHCP_req_renew_checksum2 >> 16)); // again, then complement



always @ *
case(rdaddress)
//---------- UDP/IP packet --------
// Ethernet preamble
0 : pkt_data <= 8'h55;
1 : pkt_data <= 8'h55;
2 : pkt_data <= 8'h55;
3 : pkt_data <= 8'h55;
4 : pkt_data <= 8'h55;
5 : pkt_data <= 8'h55;
6 : pkt_data <= 8'h55;
7 : pkt_data <= 8'hD5;
// Ethernet header
8 : pkt_data <= PC_MAC[47:40];
9 : pkt_data <= PC_MAC[39:32];
10: pkt_data <= PC_MAC[31:24];
11: pkt_data <= PC_MAC[23:16];
12: pkt_data <= PC_MAC[15:8];
13: pkt_data <= PC_MAC[7:0];
14: pkt_data <= This_MAC[47:40];
15: pkt_data <= This_MAC[39:32];
16: pkt_data <= This_MAC[31:24];
17: pkt_data <= This_MAC[23:16];
18: pkt_data <= This_MAC[15:8];
19: pkt_data <= This_MAC[7:0];
20: pkt_data <= 8'h08;
21: pkt_data <= 8'h00;
// IP header
22: pkt_data <= 8'h45; // Version
23: pkt_data <= 8'h00; // Type of service
24: pkt_data <= 8'h04; // length ***** CHANGE CHECKSUM IF LENGTH CHANGES *****

вырезал кусок ....

858: pkt_data <= 8'h00;
859: pkt_data <= 8'h00;

default: pkt_data <= 0;
endcase

// to calculate length; 8 + (end - DHCP_start + 1) + nulls + 202

assign DHCP_length = 16'd8 + (16'd367 - 16'd350 + 16'd1) + 16'd24 + 16'd202; // 8 + 244
assign UDP_DHCP_length = DHCP_length + 16'd20;

assign DHCP_req_length = 16'd8 + (16'd479 - 16'd450 + 16'd1) + 16'd24 + 16'd202; // 8 + 256
assign UDP_DHCP_req_length = DHCP_req_length + 16'd20;

assign DHCP_req_renew_length = 16'd8 + (16'd779 - 16'd750 + 16'd1) + 16'd12 + 16'd202; // 8 + 244
assign UDP_DHCP_req_renew_length = DHCP_req_renew_length + 16'd20;


always @ (negedge Tx_clock_2 or posedge Reset) // clock at half speed since we read bytes but write nibbles
begin
if (Reset)
begin
state_Tx <= RESET;
end else begin
case(state_Tx)

RESET:
begin
LED <= 1'b0;
sync_Tx_CTL <= 1'b0;
data_count <= 0;
reset_CRC <= 0;
rdaddress <= 0;
ARP_sent <= 0;
ping_sent <= 0;
ping_check_temp <= 0; // reset ping check sum calculation
ck_count <= 0;
zero_count <= 0;
DHCP_discover_sent <= 0;
DHCP_request_sent <= 0;
METIS_discover_sent <= 0;
DHCP_request_renew_sent <= 0;
interframe <= 0;
erase_done_ACK <= 0;
send_more_ACK <= 0;
IP_count <= 0;

if (IF_rst)
state_Tx <= RESET;
else begin

if (run == 1'b0) begin
sequence_number <= 0; // reset sequence numbers when not running.
spec_seq_number <= 0;
end

//--------


if (Send_ARP) begin // Pending ARP request
rdaddress <= 100; // point to start of ARP table
state_Tx <= ARP;
end
else if (ping_reply)begin
rdaddress <= 200; // point to ping checksum code
state_Tx <= PING1;
end

else
if (send_pll_data) begin
rdaddress <= 0;
state_Tx <= PLL_DATA;
end

else state_Tx <= RESET;
end
end

// start sending UDP/IP data
UDP:
begin
end_point <= 8'h06; // USB I&Q equivalent end point - EP6
if (rdaddress != 58) // keep sending until we reach the end of the fixed data
begin
Tx_data <= pkt_data;
sync_Tx_CTL <= 1'b1; // enable write to PHY
rdaddress <= rdaddress + 1'd1;
state_Tx <= UDP;
end
else
// read the Tx fifo data
begin
if (data_count < 1024) begin
Tx_data <= PHY_Tx_data;
data_count <= data_count + 1'd1; // increment loop counter
state_Tx <= UDP;
end
else begin
temp_CRC32 <= CRC32; // grab the CRC data since it will change next clock pulse
Tx_data <= CRC32[7:0]; // send CRC32 to PHY
rdaddress <= 58; // point to end of CRC table
sequence_number <= sequence_number + 1'b1; // increment sequence number
state_Tx <= CRC;
end
end // done, so now add the remainder of the CRC32

if (rdaddress == 57) Tx_fifo_rdreq <= 1'b1; // enable read from Tx_fifo on next clock
if (data_count == 1023) Tx_fifo_rdreq <= 1'b0; // stop reading from Tx_fifo

if (rdaddress == 7)
reset_CRC <= 1'b1; // start CRC32 generation
else
reset_CRC <= 1'b0;
end


// respond to pending ARP request, just read straight through the table
ARP:
begin

if (rdaddress != 150) begin
sync_Tx_CTL <= 1'b1; // enable write to PHY
Tx_data <= pkt_data;
rdaddress <= rdaddress + 1'd1;
state_Tx <= ARP;
end
else if (zero_count < 18)begin // send 18 x 0x00s
Tx_data <= 8'h00;
zero_count <= zero_count + 1'b1;
state_Tx <= ARP;
end
else begin
ARP_sent <= 1'b1; // set APR sent flag
temp_CRC32 <= CRC32; // grab the CRC data since it will change next clock pulse
Tx_data <= CRC32[7:0]; // send CRC32 to PHY
rdaddress <= 58; // point to end of CRC table
state_Tx <= CRC;
end

if (rdaddress == 107)
reset_CRC <= 1'b1; // start CRC32 generation
else
reset_CRC <= 1'b0;

end

// Calculate ping checksum. Ping data is in bytes, convert to 16 bits then
// sum, apply one's complement then complement
PING1:
begin
if (ck_count != (Length - 24)) begin // add all the ping data as 16 bits,
ping_check_temp <= ping_check_temp + {16'b0,ping_data[ck_count], ping_data[ck_count + 1]};
ck_count <= ck_count + 8'd2; // get next two bytes
state_Tx <= PING1;
end
else if (ping_check_temp >> 16 != 0) begin // do one's complement
ping_check_temp <= ((ping_check_temp & 32'h0000FFFF) + (ping_check_temp >> 16));
state_Tx <= PING1;
end
else begin // complement and move to next state
ping_check_sum <= ~ping_check_temp[15:0];
state_Tx <= PING2;
end
end

// respond to ping
PING2:
begin
if (rdaddress != 246) // keep sending until we reach the end of the fixed data
begin
Tx_data <= pkt_data;
sync_Tx_CTL <= 1'b1; // enable write to PHY
rdaddress <= rdaddress + 1'b1;
state_Tx <= PING2;
end
else if (data_count < (Length - 24)) begin // send contents of ping_data in bytes
Tx_data <= ping_data[data_count];
data_count <= data_count + 1'd1; // increment loop counter
state_Tx <= PING2;
end
else begin
ping_sent <= 1'b1; // set ping sent flag
temp_CRC32 <= CRC32; // grab the CRC data since it will change next clock pulse
Tx_data <= CRC32[7:0]; // send CRC32 to PHY
rdaddress <= 58; // point to end of CRC table
state_Tx <= CRC;
end

if (rdaddress == 207)
reset_CRC <= 1'b1; // start CRC32 generation
else
reset_CRC <= 1'b0;
end

// send raw data
PLL_DATA:
begin
if (rdaddress != 58) // keep sending until we reach the end of the fixed data
begin // but skip sequence number
Tx_data <= pkt_data;
sync_Tx_CTL <= 1'b1; // enable write to PHY
rdaddress <= rdaddress + 1'd1;
state_Tx <= PLL_DATA;
end
else
// read the Tx fifo data
begin
if (sp_data_count == 0) begin // Первым должны передать код команды
Tx_data <= 8'h80; // Код 0x80 - пакет состояния PLL
sp_data_count <= sp_data_count + 1'b1; // increment loop counter
state_Tx <= PLL_DATA;
end
else if (sp_data_count <=33) begin // отправляем массив данных
Tx_data <= pll_data[sp_data_count-1];
sp_data_count <= sp_data_count + 1'b1; // increment loop counter
state_Tx <= PLL_DATA;
end
else if (sp_data_count != 1024) begin // заполняем оставшееся место
Tx_data <= 8'h55;
sp_data_count <= sp_data_count + 1'b1; // increment loop counter
state_Tx <= PLL_DATA;
end
else begin
sp_data_count <= 0; // reset data counter for next time
temp_CRC32 <= CRC32; // grab the CRC data since it will change next clock pulse
Tx_data <= CRC32[7:0]; // send CRC32 to PHY
rdaddress <= 58; // point to end of CRC table
sequence_number <= sequence_number + 1'b1; // increment sequence number
state_Tx <= CRC;
end
end // done, so now add the remainder of the CRC32

if (rdaddress == 7)
reset_CRC <= 1'b1; // start CRC32 generation
else
reset_CRC <= 1'b0;
end





// add remainder of CRC32
CRC:
begin
if (rdaddress != 61) begin
Tx_data <= pkt_data;
rdaddress <= rdaddress + 1'b1;
state_Tx <= CRC;
end
else begin
sync_Tx_CTL <= 1'b0; // disable PHY write
if (interframe == 10) begin // delay between frames should be 960/96nS min
state_Tx <= RESET; // send complete, loop back to start
end
else interframe <= interframe + 1'b1;
end
end


default: state_Tx <= RESET;


endcase
end
end



//------------------------------
// 802.3 CRC32 Calculation
//-------------------------------

CRC32 CRC32_inst(.rst(reset_CRC),.clk(Tx_clock_2), .data(Tx_data), .crc(CRC32));



//-----------------------------------------------------------
// Send data to PHY
//-----------------------------------------------------------


// Data to send is in Tx_data in bytes.
// For 100T, when sync_Tx_CTL is true we alternate sending low and high nibbles



always @ (negedge Tx_clock or posedge Reset)
begin
if (Reset) PHY_state <=0;
else
case (PHY_state)
// send low nibble
0: begin
if (sync_Tx_CTL) begin
sync_TD <= Tx_data[3:0];
PHY_state <= 1'b1;
end
else PHY_state <= 0;
end
// now send high nibble
1: begin
sync_TD <= Tx_data[7:4];
PHY_state <= 0;
end

endcase
end

// sync data to PHY on Tx clock, clock PHY on ~Tx_clock so we clock in middle of data

always @ (posedge Tx_clock)
begin
TD <= sync_TD;
Tx_CTL <= sync_Tx_CTL;
end




reg [3:0]TD;
reg Tx_CTL;

endmodule
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Digi
сообщение Mar 23 2015, 18:14
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 150
Регистрация: 20-08-04
Пользователь №: 529



К своему стыду, признаюсь, в данном проекте с констрейнами у меня полный ступор. Я и до этого с ними не дружил, в силу неполного понимания процесса их описания. Может направите меня в более менее доступное разъяснение, как с ними работать.

По поводу кривизны проекта: за основу был взят опенсорсный проект, я его модифицировал до нужного мне функционала.

Torpeda, из CLOCK*_50 - используется только CLOCK_50, остальные я ухитрился автоматом прописать.
PHY_RX_CLOCK и PHY_TX_CLOCK - в принципе друг с другом синхронны, но сдвинуты по фазе, так как берутся с разных источников (выходов PHY).

bogaev_roman, time quest ничего разумного не скажет, потому что констрейны прописаны криво.

Цитата
Асинхронщина какая-нибудь. Внутри замысловато перемежаются posedge и negedge двух клоков, причем один взят с триггера-делителя... Если тайминг аналайзер говорит, что все хорошо, то можно, конечно поверить, но я бы был начеку. Или сброс асинхронный приходит откуда-нибудь из логики не подсинхронизированный к клоку.

alexadmin, сброс в процессе работы не приходит. Но почему машина состояний вываливается и не отрабатывается default ?


Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 13:31
Рейтинг@Mail.ru


Страница сгенерированна за 0.01423 секунд с 7
ELECTRONIX ©2004-2016