Ethernet MAC works!

This commit is contained in:
Wiesner András 2024-11-29 23:57:14 +01:00
parent 800379dbeb
commit fbe6667fe6
19 changed files with 4633 additions and 176 deletions

View File

@ -1,17 +1,25 @@
`timescale 1ns / 1ps
//-----------------------------------------------------------------------------
// Copyright (C) 2009 OutputLogic.com
// This source file may be used and distributed without restriction
// provided that this copyright statement is not removed from the file
// and that any derivative work contains the original copyright notice
// and the associated disclaimer.
//
// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//-----------------------------------------------------------------------------
// CRC module for data[7:0] , crc[31:0]=1+x^1+x^2+x^4+x^5+x^7+x^8+x^10+x^11+x^12+x^16+x^22+x^23+x^26+x^32;
//-----------------------------------------------------------------------------
// THIS IS GENERATED VERILOG CODE.
// https://bues.ch/h/crcgen
//
// This code is Public Domain.
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
// RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
// USE OR PERFORMANCE OF THIS SOFTWARE.
// CRC polynomial coefficients: x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
// 0xEDB88320 (hex)
// CRC width: 32 bits
// CRC shift direction: right (little endian)
// Input word width: 8 bits
module crc32(
input wire clk,
input wire rst,
@ -22,52 +30,55 @@ module crc32(
output wire [31:0] crc_out
);
reg [31:0] lfsr_q,lfsr_c;
reg [31:0] result;
assign crc_out = ~lfsr_q;
function automatic [31:0] crc;
input [31:0] crcIn;
input [7:0] data_in;
begin
crc[0] = crcIn[2] ^ crcIn[8] ^ data_in[2];
crc[1] = crcIn[0] ^ crcIn[3] ^ crcIn[9] ^ data_in[0] ^ data_in[3];
crc[2] = crcIn[0] ^ crcIn[1] ^ crcIn[4] ^ crcIn[10] ^ data_in[0] ^ data_in[1] ^ data_in[4];
crc[3] = crcIn[1] ^ crcIn[2] ^ crcIn[5] ^ crcIn[11] ^ data_in[1] ^ data_in[2] ^ data_in[5];
crc[4] = crcIn[0] ^ crcIn[2] ^ crcIn[3] ^ crcIn[6] ^ crcIn[12] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[6];
crc[5] = crcIn[1] ^ crcIn[3] ^ crcIn[4] ^ crcIn[7] ^ crcIn[13] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[7];
crc[6] = crcIn[4] ^ crcIn[5] ^ crcIn[14] ^ data_in[4] ^ data_in[5];
crc[7] = crcIn[0] ^ crcIn[5] ^ crcIn[6] ^ crcIn[15] ^ data_in[0] ^ data_in[5] ^ data_in[6];
crc[8] = crcIn[1] ^ crcIn[6] ^ crcIn[7] ^ crcIn[16] ^ data_in[1] ^ data_in[6] ^ data_in[7];
crc[9] = crcIn[7] ^ crcIn[17] ^ data_in[7];
crc[10] = crcIn[2] ^ crcIn[18] ^ data_in[2];
crc[11] = crcIn[3] ^ crcIn[19] ^ data_in[3];
crc[12] = crcIn[0] ^ crcIn[4] ^ crcIn[20] ^ data_in[0] ^ data_in[4];
crc[13] = crcIn[0] ^ crcIn[1] ^ crcIn[5] ^ crcIn[21] ^ data_in[0] ^ data_in[1] ^ data_in[5];
crc[14] = crcIn[1] ^ crcIn[2] ^ crcIn[6] ^ crcIn[22] ^ data_in[1] ^ data_in[2] ^ data_in[6];
crc[15] = crcIn[2] ^ crcIn[3] ^ crcIn[7] ^ crcIn[23] ^ data_in[2] ^ data_in[3] ^ data_in[7];
crc[16] = crcIn[0] ^ crcIn[2] ^ crcIn[3] ^ crcIn[4] ^ crcIn[24] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4];
crc[17] = crcIn[0] ^ crcIn[1] ^ crcIn[3] ^ crcIn[4] ^ crcIn[5] ^ crcIn[25] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5];
crc[18] = crcIn[0] ^ crcIn[1] ^ crcIn[2] ^ crcIn[4] ^ crcIn[5] ^ crcIn[6] ^ crcIn[26] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6];
crc[19] = crcIn[1] ^ crcIn[2] ^ crcIn[3] ^ crcIn[5] ^ crcIn[6] ^ crcIn[7] ^ crcIn[27] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7];
crc[20] = crcIn[3] ^ crcIn[4] ^ crcIn[6] ^ crcIn[7] ^ crcIn[28] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7];
crc[21] = crcIn[2] ^ crcIn[4] ^ crcIn[5] ^ crcIn[7] ^ crcIn[29] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7];
crc[22] = crcIn[2] ^ crcIn[3] ^ crcIn[5] ^ crcIn[6] ^ crcIn[30] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6];
crc[23] = crcIn[3] ^ crcIn[4] ^ crcIn[6] ^ crcIn[7] ^ crcIn[31] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7];
crc[24] = crcIn[0] ^ crcIn[2] ^ crcIn[4] ^ crcIn[5] ^ crcIn[7] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7];
crc[25] = crcIn[0] ^ crcIn[1] ^ crcIn[2] ^ crcIn[3] ^ crcIn[5] ^ crcIn[6] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6];
crc[26] = crcIn[0] ^ crcIn[1] ^ crcIn[2] ^ crcIn[3] ^ crcIn[4] ^ crcIn[6] ^ crcIn[7] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7];
crc[27] = crcIn[1] ^ crcIn[3] ^ crcIn[4] ^ crcIn[5] ^ crcIn[7] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7];
crc[28] = crcIn[0] ^ crcIn[4] ^ crcIn[5] ^ crcIn[6] ^ data_in[0] ^ data_in[4] ^ data_in[5] ^ data_in[6];
crc[29] = crcIn[0] ^ crcIn[1] ^ crcIn[5] ^ crcIn[6] ^ crcIn[7] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[6] ^ data_in[7];
crc[30] = crcIn[0] ^ crcIn[1] ^ crcIn[6] ^ crcIn[7] ^ data_in[0] ^ data_in[1] ^ data_in[6] ^ data_in[7];
crc[31] = crcIn[1] ^ crcIn[7] ^ data_in[1] ^ data_in[7];
end
endfunction
always @(*) begin
lfsr_c[0] = lfsr_q[24] ^ lfsr_q[30] ^ data_in[0] ^ data_in[6];
lfsr_c[1] = lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[0] ^ data_in[1] ^ data_in[6] ^ data_in[7];
lfsr_c[2] = lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[6] ^ data_in[7];
lfsr_c[3] = lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[31] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[7];
lfsr_c[4] = lfsr_q[24] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[30] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6];
lfsr_c[5] = lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7];
lfsr_c[6] = lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7];
lfsr_c[7] = lfsr_q[24] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[29] ^ lfsr_q[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[7];
lfsr_c[8] = lfsr_q[0] ^ lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[27] ^ lfsr_q[28] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4];
lfsr_c[9] = lfsr_q[1] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[28] ^ lfsr_q[29] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5];
lfsr_c[10] = lfsr_q[2] ^ lfsr_q[24] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[29] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5];
lfsr_c[11] = lfsr_q[3] ^ lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[27] ^ lfsr_q[28] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4];
lfsr_c[12] = lfsr_q[4] ^ lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[30] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6];
lfsr_c[13] = lfsr_q[5] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[29] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7];
lfsr_c[14] = lfsr_q[6] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7];
lfsr_c[15] = lfsr_q[7] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[31] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7];
lfsr_c[16] = lfsr_q[8] ^ lfsr_q[24] ^ lfsr_q[28] ^ lfsr_q[29] ^ data_in[0] ^ data_in[4] ^ data_in[5];
lfsr_c[17] = lfsr_q[9] ^ lfsr_q[25] ^ lfsr_q[29] ^ lfsr_q[30] ^ data_in[1] ^ data_in[5] ^ data_in[6];
lfsr_c[18] = lfsr_q[10] ^ lfsr_q[26] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[2] ^ data_in[6] ^ data_in[7];
lfsr_c[19] = lfsr_q[11] ^ lfsr_q[27] ^ lfsr_q[31] ^ data_in[3] ^ data_in[7];
lfsr_c[20] = lfsr_q[12] ^ lfsr_q[28] ^ data_in[4];
lfsr_c[21] = lfsr_q[13] ^ lfsr_q[29] ^ data_in[5];
lfsr_c[22] = lfsr_q[14] ^ lfsr_q[24] ^ data_in[0];
lfsr_c[23] = lfsr_q[15] ^ lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[30] ^ data_in[0] ^ data_in[1] ^ data_in[6];
lfsr_c[24] = lfsr_q[16] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[31] ^ data_in[1] ^ data_in[2] ^ data_in[7];
lfsr_c[25] = lfsr_q[17] ^ lfsr_q[26] ^ lfsr_q[27] ^ data_in[2] ^ data_in[3];
lfsr_c[26] = lfsr_q[18] ^ lfsr_q[24] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[30] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[6];
lfsr_c[27] = lfsr_q[19] ^ lfsr_q[25] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[31] ^ data_in[1] ^ data_in[4] ^ data_in[5] ^ data_in[7];
lfsr_c[28] = lfsr_q[20] ^ lfsr_q[26] ^ lfsr_q[29] ^ lfsr_q[30] ^ data_in[2] ^ data_in[5] ^ data_in[6];
lfsr_c[29] = lfsr_q[21] ^ lfsr_q[27] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[3] ^ data_in[6] ^ data_in[7];
lfsr_c[30] = lfsr_q[22] ^ lfsr_q[28] ^ lfsr_q[31] ^ data_in[4] ^ data_in[7];
lfsr_c[31] = lfsr_q[23] ^ lfsr_q[29] ^ data_in[5];
end // always
always @(posedge clk, posedge rst) begin
if(rst | clear) begin
lfsr_q <= {32{1'b0}};
end
else begin
lfsr_q <= crc_en ? lfsr_c : lfsr_q;
end
end // always
always @(posedge clk) begin
if(rst | clear) begin
result <= 32'hFFFFFFFF;
end
else begin
result <= crc_en ? crc(result, data_in) : result;
end
end // always
assign crc_out = ~result;
endmodule // crc32

View File

@ -1,5 +1,7 @@
`timescale 1ns / 1ps
`include "src/eth/crc32.v"
module crc32_test;
// Inputs

View File

@ -5,7 +5,6 @@
`include "src/rmii/rmii_transmit_controller.v"
module eth_mac #(
parameter MAIN_CLK_FREQ = 200,
parameter MEM_DATA_WIDTH = 8,
parameter MEM_ADDR_WIDTH = 12,
@ -22,7 +21,6 @@ module eth_mac #(
input [CTRL_WORD_WIDTH-1:0] ctrl_word,
output REF_CLK,
output TXEN,
output [1:0] TXD
@ -30,17 +28,6 @@ module eth_mac #(
//input [1:0] RXD
);
wire REF_pulse;
rmii_clock_generator #(
.MAIN_CLK_FREQ(MAIN_CLK_FREQ)
) clk_gen (
.clk(clk),
.rst(rst),
.REF_CLK(REF_CLK),
.rising(REF_pulse)
);
wire tx_wrt;
wire tx_not_full;
wire transmitter_busy;
@ -53,7 +40,6 @@ rmii_transmit_controller #(
.rst(rst),
.clear(clear),
.REF_pulse(REF_pulse),
.data_in(tx_data_in),
.wrt(tx_wrt),
.not_full(tx_not_full),
@ -67,7 +53,7 @@ wire [MEM_ADDR_MSB:0] frame_addr = ctrl_word[MEM_ADDR_WIDTH-1:0];
wire [LEN_MSB:0] frame_len = ctrl_word[MEM_ADDR_WIDTH + LEN_WIDTH - 1:MEM_ADDR_WIDTH];
wire start = ctrl_word[CTRL_WORD_WIDTH - 1];
wire mem_acc_busy;
//wire mem_acc_busy;
mac_memory_access_controller #(
.DATA_WIDTH(MEM_DATA_WIDTH),
@ -85,7 +71,7 @@ mac_memory_access_controller #(
.frame_addr(frame_addr),
.frame_len(frame_len),
.busy(mem_acc_busy),
.busy(/*mem_acc_busy*/),
.tx_data_in(tx_data_in),
.tx_not_full(tx_not_full),
.tx_wrt(tx_wrt)

View File

@ -30,8 +30,8 @@ module mac_memory_access_controller #(
// --------------
wire clear_crc = (state != FETCH_FRAME);
wire crc_en;
wire clear_crc = (state == IDLE);
wire crc_en = (state == FETCH_FRAME) && tx_not_full;
wire [31:0] crc_out;
crc32 crc32_engine (
@ -61,7 +61,7 @@ wire frame_params_valid = frame_len != 0;
// frame setup and transmission
localparam PREAMBLE_PATTERN = 8'h55; // Ethernet preamble pattern
localparam SOF_PATTERN = 8'h56; // Ethernet Start-of-Frame pattern
localparam SOF_PATTERN = 8'hD5; // Ethernet Start-of-Frame pattern
localparam PREAMBLE_LEN = 8; // length of the frame preamble
reg [2:0] preamble_idx; // index of the preamble byte being sent
reg [1:0] crc_idx; // index of the CRC bytes
@ -85,7 +85,7 @@ begin
IDLE:
begin
mem_addr <= frame_addr;
len_left <= frame_len - 1;
len_left <= frame_len - 1'b1;
preamble_idx <= 0;
crc_idx <= 0;
end
@ -94,7 +94,7 @@ begin
begin
if (tx_not_full)
begin
preamble_idx <= preamble_idx + 1;
preamble_idx <= preamble_idx + 1'b1;
end
end
@ -104,8 +104,8 @@ begin
begin
if (tx_not_full)
begin
mem_addr <= mem_addr + 1;
len_left <= len_left - 1;
mem_addr <= mem_addr + 1'b1;
len_left <= len_left - 1'b1;
end
end
end
@ -114,7 +114,7 @@ begin
begin
if (tx_not_full)
begin
crc_idx <= cdc_idx + 1;
crc_idx <= crc_idx + 1'b1;
end
end
@ -127,7 +127,7 @@ begin
IDLE: if (start && frame_params_valid) state <= INSERT_PREAMBLE;
INSERT_PREAMBLE: if (preamble_idx == (PREAMBLE_LEN - 1)) state <= FETCH_FRAME;
FETCH_FRAME: if ((len_left == 0) && tx_not_full) state <= APPEND_CRC;
APPEND_CRC: if (crc_idx == (3)) state <= WAIT_TX_COMPL;
APPEND_CRC: if ((crc_idx == (3)) && tx_not_full) state <= WAIT_TX_COMPL;
WAIT_TX_COMPL: if (!transmitter_busy) state <= IDLE;
default: state <= IDLE;
endcase
@ -137,7 +137,7 @@ end
// combinatorial outputs
assign busy = (state != IDLE);
//assign tx_data_in = mem_data;
assign tx_wrt = (state == FETCH_FRAME) || (state == INSERT_PREAMBLE);
assign tx_wrt = (state == FETCH_FRAME) || (state == INSERT_PREAMBLE) || (state == APPEND_CRC);
// assign data output
always @(*)
@ -146,9 +146,9 @@ begin
INSERT_PREAMBLE: tx_data_in <= (preamble_idx == (PREAMBLE_LEN - 1)) ? SOF_PATTERN : PREAMBLE_PATTERN;
APPEND_CRC:
case (crc_idx)
2'd0: tx_data_in <= crc_out[31:24];
2'd1: tx_data_in <= crc_out[23:16];
2'd2: tx_data_in <= crc_out[15:8];
2'd3: tx_data_in <= crc_out[31:24];
2'd2: tx_data_in <= crc_out[23:16];
2'd1: tx_data_in <= crc_out[15:8];
default: tx_data_in <= crc_out[7:0];
endcase
default: tx_data_in <= mem_data;

View File

@ -51,7 +51,7 @@ begin
if (will_push)
begin
mem[push_idx] <= in;
push_idx <= push_idx + 1;
push_idx <= push_idx + 1'b1;
end
end
end
@ -70,7 +70,7 @@ begin
if (will_pop)
begin
out <= mem[pop_idx];
pop_idx <= pop_idx + 1;
pop_idx <= pop_idx + 1'b1;
out_valid <= 1;
end
else
@ -91,12 +91,12 @@ begin
begin
if (will_push && !will_pop)
begin
level <= level + 1;
level <= level + 1'b1;
end
if (will_pop && !will_push)
begin
level <= level - 1;
level <= level - 1'b1;
end
end
end

View File

@ -1,45 +1,80 @@
`timescale 1ns / 1ps
`include "src/eth/eth_mac.v"
module jitmeas_top(
input wire clk50M, // 50MHz clock input
input wire rstbt,
input clk50, rst, clear,
//output wire clk200M
output wire [16:4] aio
input btn,
output REF_CLK,
//input [1:0] RXD,
//input CRS_DV,
output [1:0] TXD,
output TXEN
);
wire rst = ~rstbt;
localparam MAIN_CLK_FREQ = 150; // Main Clock Frequency in MHz
localparam MEM_DATA_WIDTH = 8; // Memory word size
localparam MEM_ADDR_WIDTH = 12; // Memory address size
/* Main Clock Generation module */
wire main_pll_locked;
wire clk200M;
wire [MEM_DATA_WIDTH-1:0] stream_mem_data;
wire [MEM_ADDR_WIDTH-1:0] stream_mem_addr;
MainPLL main_pll (
// Clock in ports
.In_50MHz(clk50M), // IN
wire [31:0] ctrl_word;
// Clock out ports
.Out_200MHz(clk200M), // OUT
eth_mac #(
.MEM_DATA_WIDTH(MEM_DATA_WIDTH),
.MEM_ADDR_WIDTH(MEM_ADDR_WIDTH)
) eth_mac_inst (
.clk(clk50),
.rst(rst),
.clear(1'b0),
// Status and control signals
.RESET(rst), // IN
.LOCKED(main_pll_locked) // OUT
);
localparam MAIN_CLK_FREQ = 200; // Main Clock Frequency in MHz
assign aio[16:5] = 0;
eth_mac eth_mac_inst (
.clk(clk200M),
.rst(rst),
.mem_data(stream_mem_data),
.mem_addr(stream_mem_addr),
.REF_CLK(REF_CLK),
//.TXEN(TXEN),
//.TXD(TXD),
.CRS_DV(0),
.RXD(0)
.ctrl_word(ctrl_word),
.TXEN(TXEN),
.TXD(TXD)
);
StreamMemory stream_mem (
/* PORT A */
.clka(clk50), // input clka
.ena(1'b0), // input ena
.wea(1'b0), // input [0 : 0] wea
.addra(12'b0), // input [10 : 0] addra
.dina(8'b0), // input [7 : 0] dina
/* PORT B */
.clkb(clk50), // input clkb
.rstb(rst), // input rstb
.addrb(stream_mem_addr), // input [10 : 0] addrb
.doutb(stream_mem_data) // output [7 : 0] doutb
);
/* button handling */
reg btn_prev;
always @(posedge clk50)
begin
if (rst | clear)
begin
btn_prev <= 0;
end
else
begin
btn_prev <= btn;
end
end
localparam FRAME_LENGTH = 100;
assign ctrl_word[30:0] = 31'b0 | (FRAME_LENGTH << MEM_ADDR_WIDTH) | (0);
assign ctrl_word[31] = ~btn_prev && btn;
assign REF_CLK = clk50;
endmodule

169
src/logsys_sp6_board.ucf Normal file
View File

@ -0,0 +1,169 @@
# LOGSYS XC6SLX9-2TQG144C Demo Board FPGA lábkiosztás v1.0
# A fájl az összes jelet tartlmazza, a kivezetés specifikációkat
# inaktív, megjegyzés állapotban tartva.
# Egy adott projektben csak a ténylegesen használt jeleket aktíváljuk,
# elkerülendő az ERROR és WARNING üzeneteket.
# A VccAUX tápfeszültség 3,3 V.
CONFIG VCCAUX=3.3;
# 50 MHz órajelgenerátor
NET clk50M LOC=P55 | IOSTANDARD=LVCMOS33 | TNM_NET=tnm_clk50M;
TIMESPEC TS_clk50M = PERIOD tnm_clk50M 50000 kHz;
# Manuális RST nyomógomb (aktív alacsony)
NET rstbt LOC=P67 | IOSTANDARD=LVCMOS33 | PULLUP | TIG;
# A LOGSYS fejlesztői port vonalai.
#NET dev_mosi LOC=P104 | IOSTANDARD=LVCMOS33;
#NET dev_miso LOC=P144 | IOSTANDARD=LVCMOS33;
#NET dev_clk LOC=P95 | IOSTANDARD=LVCMOS33;
#NET dev_rst LOC=P94 | IOSTANDARD=LVCMOS33;
# 3 darab aktív magas nyomógomb, balról jobbra számozva.
#NET bt<2> LOC=P61 | IOSTANDARD=LVCMOS33 | PULLDOWN;
#NET bt<1> LOC=P62 | IOSTANDARD=LVCMOS33 | PULLDOWN;
NET bt<0> LOC=P66 | IOSTANDARD=LVCMOS33 | PULLDOWN;
# A CPLD interfész vonalai. A cpld_jtagen jelet
# mindig logikai alacsony szinttel hajtsuk meg!
#NET cpld_jtagen LOC=P82 | IOSTANDARD=LVCMOS33;
#NET cpld_rstn LOC=P74 | IOSTANDARD=LVCMOS33;
#NET cpld_clk LOC=P78 | IOSTANDARD=LVCMOS33;
#NET cpld_load LOC=P80 | IOSTANDARD=LVCMOS33;
#NET cpld_mosi LOC=P81 | IOSTANDARD=LVCMOS33;
#NET cpld_miso LOC=P79 | IOSTANDARD=LVCMOS33;
# Az SPI interfész vonalai. A nem használt SPI perifériák
# kiválasztó jeleit logikai magas szinttel hajtsuk meg!
#NET spi_sdcard_csn LOC=P75 | IOSTANDARD=LVCMOS33;
#NET spi_flash_csn LOC=P38 | IOSTANDARD=LVCMOS33;
#NET spi_lcd_csn LOC=P69 | IOSTANDARD=LVCMOS33;
#NET spi_mosi LOC=P64 | IOSTANDARD=LVCMOS33;
#NET spi_miso LOC=P65 | IOSTANDARD=LVCMOS33;
#NET spi_clk LOC=P70 | IOSTANDARD=LVCMOS33;
# SRAM és SDRAM memóriák. A nem használt memóriák
# kiválasztó jeleit logikai magas szinttel hajtsuk meg!
#NET mem_addr<0> LOC=P45 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_addr<1> LOC=P46 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_addr<2> LOC=P47 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_addr<3> LOC=P48 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_addr<4> LOC=P59 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_addr<5> LOC=P58 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_addr<6> LOC=P57 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_addr<7> LOC=P56 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_addr<8> LOC=P51 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_addr<9> LOC=P50 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_addr<10> LOC=P44 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_addr<11> LOC=P41 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_addr<12> LOC=P40 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_addr<13> LOC=P39 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; #SDRAM BA0
#NET mem_addr<14> LOC=P43 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; #SDRAM BA1
#NET mem_addr<15> LOC=P33 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; #SDRAM /RAS
#NET mem_addr<16> LOC=P34 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; #SDRAM /CAS
#NET mem_addr<17> LOC=P60 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_data<0> LOC=P6 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<1> LOC=P8 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<2> LOC=P10 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<3> LOC=P12 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<4> LOC=P15 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<5> LOC=P17 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<6> LOC=P22 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<7> LOC=P24 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<8> LOC=P23 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<9> LOC=P21 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<10> LOC=P16 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<11> LOC=P14 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<12> LOC=P11 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<13> LOC=P9 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<14> LOC=P7 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_data<15> LOC=P5 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | KEEPER;
#NET mem_wen LOC=P29 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_lbn LOC=P27 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET mem_ubn LOC=P26 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET sram_csn LOC=P1 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET sram_oen LOC=P2 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET sdram_clk LOC=P30 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET sdram_cke LOC=P32 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
#NET sdram_csn LOC=P35 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
# LOGSYS "A" bővítőcsatlakozó (szemből nézve a 20 pólusú
# csatlakozó nem használható pontjait x-el jelölve).
# --------------------------------------------------------
# | x |aio15|aio13|aio11|aio9 |aio7 |aio5 | 3V3 |GND | x |
# --------------------------------------------------------
# | x |aio16|aio14|aio12|aio10|aio8 |aio6 |aio4 | 5V | x |
# --------------------------------------------------------
NET aio<16> LOC=P126 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # Diff. 6N
NET aio<15> LOC=P127 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # Diff. 6P
NET aio<14> LOC=P131 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # Diff. 5N
NET aio<13> LOC=P132 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # Diff. 5P
NET aio<12> LOC=P133 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # Diff. 4N
NET aio<11> LOC=P134 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # Diff. 4P
NET aio<10> LOC=P137 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # Diff. 3N
NET aio<9> LOC=P138 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # Diff. 3P
NET aio<8> LOC=P139 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # Diff. 2N
NET aio<7> LOC=P140 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # Diff. 2P
NET aio<6> LOC=P141 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # Diff. 1N
NET aio<5> LOC=P142 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # Diff. 1P
NET aio<4> LOC=P143 | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST;
# LOGSYS "B" bővítőcsatlakozó (szemből nézve a 20 pólusú
# csatlakozó nem használható pontjait x-el jelölve).
# --------------------------------------------------------
# | x |bio15|bio13|bio11|bio9 |bio7 |bio5 | 3V3 |GND | x |
# --------------------------------------------------------
# | x |bio16|bio14|bio12|bio10|bio8 |bio6 |bio4 | 5V | x |
# --------------------------------------------------------
#NET bio<16> LOC=P84 | IOSTANDARD=LVCMOS33; # Diff. 6N
#NET bio<15> LOC=P85 | IOSTANDARD=LVCMOS33; # Diff. 6P
#NET bio<14> LOC=P87 | IOSTANDARD=LVCMOS33; # Diff. 5N
#NET bio<13> LOC=P88 | IOSTANDARD=LVCMOS33; # Diff. 5P
#NET bio<12> LOC=P92 | IOSTANDARD=LVCMOS33; # Diff. 4N
#NET bio<11> LOC=P93 | IOSTANDARD=LVCMOS33; # Diff. 4P
#NET bio<10> LOC=P97 | IOSTANDARD=LVCMOS33; # Diff. 3N
#NET bio<9> LOC=P98 | IOSTANDARD=LVCMOS33; # Diff. 3P
#NET bio<8> LOC=P99 | IOSTANDARD=LVCMOS33; # Diff. 2N
#NET bio<7> LOC=P100 | IOSTANDARD=LVCMOS33; # Diff. 2P
#NET bio<6> LOC=P101 | IOSTANDARD=LVCMOS33; # Diff. 1N
#NET bio<5> LOC=P102 | IOSTANDARD=LVCMOS33; # Diff. 1P
#NET bio<4> LOC=P83 | IOSTANDARD=LVCMOS33;
# LOGSYS "C" bővítőcsatlakozó (szemből nézve a 20 pólusú
# csatlakozó nem használható pontjait x-el jelölve).
# --------------------------------------------------------
# | x |cio15|cio13|cio11|cio9 |cio7 |cio5 | 3V3 |GND | x |
# --------------------------------------------------------
# | x |cio16|cio14|cio12|cio10|cio8 |cio6 |cio4 | 5V | x |
# --------------------------------------------------------
#NET cio<16> LOC=P114 | PULLUP | IOSTANDARD=LVCMOS33; # Diff. 6N
#NET cio<15> LOC=P115 | PULLUP | IOSTANDARD=LVCMOS33; # Diff. 6P
#NET cio<14> LOC=P116 | PULLUP | IOSTANDARD=LVCMOS33; # Diff. 5N
#NET cio<13> LOC=P117 | PULLUP | IOSTANDARD=LVCMOS33; # Diff. 5P
#NET cio<12> LOC=P118 | PULLUP | IOSTANDARD=LVCMOS33; # Diff. 4N
#NET cio<11> LOC=P119 | PULLUP | IOSTANDARD=LVCMOS33; # Diff. 4P
#NET cio<10> LOC=P120 | PULLUP | IOSTANDARD=LVCMOS33; # Diff. 3N
#NET cio<9> LOC=P121 | PULLUP | IOSTANDARD=LVCMOS33; # Diff. 3P
#NET cio<8> LOC=P123 | PULLUP | IOSTANDARD=LVCMOS33; # Diff. 2N
#NET cio<7> LOC=P124 | PULLUP | IOSTANDARD=LVCMOS33; # Diff. 2P
#NET cio<6> LOC=P111 | PULLUP | IOSTANDARD=LVCMOS33; # Diff. 1N
#NET cio<5> LOC=P112 | PULLUP | IOSTANDARD=LVCMOS33; # Diff. 1P
#NET cio<4> LOC=P105 | PULLUP | IOSTANDARD=LVCMOS33;
PIN "main_pll/clkout2_buf.O" CLOCK_DEDICATED_ROUTE = FALSE;

4098
src/lorem_ipsum_frame.coe Normal file

File diff suppressed because it is too large Load Diff

82
src/port/logsys_xc6_top.v Normal file
View File

@ -0,0 +1,82 @@
`timescale 1ns / 1ps
module logsys_xc6_top(
input wire clk50M, // 50MHz clock input
input wire rstbt,
inout wire [16:4] aio,
input wire [0:0] bt
);
wire rst = ~rstbt;
/* Main Clock Generation module */
wire clk50M90;
wire clk50M0;
MainPLL main_pll (
// Clock in ports
.In_50MHz(clk50M), // IN
// Clock out ports
.Out_50MHz_0(clk50M0),
.Out_50MHz_90(clk50M90), // OUT
// Status and control signals
.RESET(rst) // IN
// .LOCKED(/*main_pll_locked*/) // OUT
);
/* signals */
wire [1:0] TXD;
wire TXEN, REF_CLK;
//wire [1:0] RXD;
//wire CRS_DV;
/* pins */
// Unused pins
assign aio[14] = 1'b0;
assign aio[12] = 1'b0;
assign aio[10] = 1'b0;
assign aio[8] = 1'b0;
assign aio[6] = 1'b0;
assign aio[4] = 1'b0;
// Inputs
//assign RXD[0] = aio[11];
//assign RXD[1] = aio[9];
//assign CRS_DV = aio[7];
//
//assign aio[11] = 1'bZ;
//assign aio[9] = 1'bZ;
//assign aio[7] = 1'bZ;
assign aio[11] = 1'b0;
assign aio[9] = 1'b0;
assign aio[7] = 1'b0;
// Outputs
assign aio[16] = TXD[0];
assign aio[15] = TXD[1];
assign aio[13] = TXEN;
//assign aio[5] = REF_CLK;
assign aio[5] = clk50M0;
/* JitMeas module */
jitmeas_top jitmeas_inst (
.clk50(clk50M90),
.rst(rst),
.clear(1'b0),
.btn(bt[0]),
.REF_CLK(REF_CLK),
//.RXD(RXD),
//.CRS_DV(CRS_DV),
.TXD(TXD),
.TXEN(TXEN)
);
endmodule

12
src/rmii/fifo.v Normal file
View File

@ -0,0 +1,12 @@
`timescale 1ns / 1ps
module rmii_serializer #(
parameter IN_SIZE = 8,
parameter OUT_SIZE = 2,
parameter DEPTH = 16
parameter
)(
input wire
);
endmodule

View File

@ -4,15 +4,16 @@ module rmii_clock_generator #(
parameter MAIN_CLK_FREQ = 200, // frequency of the main clock
// AUTOCALCULATED
parameter CNTR_WIDTH = $clog2(MAIN_CLK_FREQ / 50), // width of the CNTR
parameter CNTR_MSB = CNTR_WIDTH - 1 // index of the counter's MSB
parameter DIV_RATIO = (MAIN_CLK_FREQ / 50), // division ratio
parameter CNTR_WIDTH = $clog2(DIV_RATIO), // width of the CNTR
parameter CNTR_MSB = CNTR_WIDTH - 1 // index of the counter's MSB
)(
input wire clk, // main clock input
input wire rst, // synchronous reset
output wire REF_CLK, // RMII REF_CLK output
output wire rising, // the next clk cycle comes with a rising edge on the REF_CLK
output wire falling // ... falling ...
output wire rising // the next clk cycle comes with a rising edge on the REF_CLK
// output wire falling // ... falling ...
);
reg [CNTR_MSB:0] ref_clk_cntr;
@ -20,18 +21,22 @@ always @(posedge clk)
begin
if (rst)
begin
ref_clk_cntr = 0;
ref_clk_cntr <= 0;
end
else
begin
ref_clk_cntr = ref_clk_cntr + 1;
if (ref_clk_cntr == (DIV_RATIO - 1'b1))
begin
ref_clk_cntr <= 0;
end
else
begin
ref_clk_cntr <= ref_clk_cntr + 1'b1;
end
end
end
assign REF_CLK = ref_clk_cntr[CNTR_MSB];
assign rising = (&ref_clk_cntr[CNTR_MSB-1:0]) & (~ref_clk_cntr[CNTR_MSB]);
assign falling = &ref_clk_cntr;
assign REF_CLK = ref_clk_cntr;
assign rising = !ref_clk_cntr;
endmodule

View File

@ -15,7 +15,9 @@ module rmii_serializer #(
output [SHIFT_SIZE-1:0] ser_out, // serialized output
input shift, // enable shifting
output empty // the inner buffer has depleted
output single, // one shift left
output empty, // the inner buffer has depleted
output exhausted // a strobe version of empty
);
// a combine reset or clear signal
@ -40,22 +42,36 @@ begin
if (load) // load the parallel data
begin
shift_work <= par_in;
shift_count <= SHIFT_COUNT - 1; // data must be shifted SHIFT_COUNT - 1 times
shift_count <= SHIFT_COUNT - 1'b1; // data must be shifted SHIFT_COUNT - 1 times
end
else if (shift)
begin
if (shift_count > 0)
begin
shift_count <= shift_count - 1; // decrease shift count
shift_count <= shift_count - 1'b1; // decrease shift count
shift_work <= DIR ? (shift_work >> SHIFT_SIZE) : (shift_work << SHIFT_SIZE); // shift the contents of the work register
end
end
end
end
reg empty_prev;
always @(posedge clk)
begin
if (rstclr)
begin
empty_prev <= 0;
end
else
begin
empty_prev <= empty;
end
end
// output logic
assign empty = (shift_count == 0); // indication for depletion
assign empty = (shift_count == 0) && !load; // empty signal
assign single = (shift_count == 1);
assign exhausted = empty && !empty_prev; // strobe for depletion
assign ser_out = DIR ? shift_work[SHIFT_SIZE-1:0] : shift_work[STORE_SIZE-1:STORE_SIZE-SHIFT_SIZE]; // serial output
endmodule

View File

@ -12,7 +12,6 @@ module rmii_transmit_controller #(
parameter SHIFT_COUNT = FIFO_DEPTH
)(
input clk, rst, clear, // general signals
input REF_pulse, // pulse that signals the coming rising edge on REF_CLK
/* FIFO signals */
input [STORAGE_MSB:0] data_in, // input data
@ -23,15 +22,18 @@ module rmii_transmit_controller #(
output reg TXEN, // transmit enable
output [1:0] TXD, // transmit data
output busy // there's an ongoing transmission
output reg busy // there's an ongoing transmission
);
wire rstclr = rst | clear;
/* TX FIFO and its signals */
wire tx_fifo_empty;
wire tx_fifo_out_valid;
wire tx_fifo_full;
wire [STORAGE_WIDTH-1:0]tx_fifo_out;
wire tx_fifo_pop = oser_empty && REF_pulse;
//wire start = wrt && !busy;
wire tx_fifo_pop = (busy && oser_empty) || oser_single;
fifo #(
.DEPTH(FIFO_DEPTH),
@ -58,26 +60,31 @@ assign not_full = !tx_fifo_full;
wire oser_load = tx_fifo_out_valid;
wire oser_empty;
//wire oser_exhausted;
wire oser_single;
wire [1:0] oser_out;
rmii_serializer #(
.STORE_SIZE(STORAGE_WIDTH),
.DIR(0) // LEFT
.DIR(1) // RIGHT
) out_serializer (
.clk(clk),
.rst(rst),
.clear(clear),
.par_in(tx_fifo_out),
.ser_out(TXD),
.ser_out(oser_out),
.load(oser_load),
.shift(REF_pulse),
.empty(oser_empty)
.shift(1'b1),
.single(oser_single),
.empty(oser_empty),
.exhausted(/*oser_exhausted*/)
);
/* TXEN control */
always @(posedge clk)
begin
if (rst | clear)
if (rstclr)
begin
TXEN <= 0;
end
@ -87,13 +94,35 @@ begin
begin
TXEN <= 1;
end
else if (REF_pulse && oser_empty && tx_fifo_empty) // deassert only when all buffers has depleted
else if (oser_empty && tx_fifo_empty) // deassert only when all buffers has depleted
begin
TXEN <= 0;
end
end
end
assign busy = TXEN;
/* busy control */
always @(posedge clk)
begin
if (rstclr)
begin
busy <= 0;
end
else
begin
if (!busy && wrt)
begin
busy <= 1;
end
if (busy && !wrt && !TXEN)
begin
busy <= 0;
end
end
end
// combinatorial output
assign TXD = TXEN ? oser_out : 2'b0;
endmodule

View File

@ -0,0 +1 @@
4C 6F 72 65 6D 20 69 70 73 75 6D 20 64 6F 6C 6F 72 20 73 69 74 20 61 6D 65 74 2C 20 63 6F 6E 73 65 63 74 65 74 75 72 20 61 64 69 70 69 73 63 69 6E 67 20 65 6C 69 74 2C 20 73 65 64 20 64 6F 20 65 69 75 73 6D 6F 64 20 74 65 6D 70 6F 72 20 69 6E 63 69 64 69 64 75 6E 74 20 75 74 20 6C 61 62 6F 72 65 20 65 74 20 64 6F 6C 6F 72 65 20 6D 61 67 6E 61 20 61 6C 69 71 75 61 2E 20 55 74 20 65 6E 69 6D 20 61 64 20 6D 69 6E 69 6D 20 76 65 6E 69 61 6D 2C 20 71 75 69 73 20 6E 6F 73 74 72 75 64 20 65 78 65 72 63 69 74 61 74 69 6F 6E 20 75 6C 6C 61 6D 63 6F 20 6C 61 62 6F 72 69 73 20 6E 69 73 69 20 75 74 20 61 6C 69 71 75 69 70 20 65 78 20 65 61 20 63 6F 6D 6D 6F 64 6F 20 63 6F 6E 73 65 71 75 61 74 2E 20 44 75 69 73 20 61 75 74 65 20 69 72 75 72 65 20 64 6F 6C 6F 72 20 69 6E 20 72 65 70 72 65 68 65 6E 64 65 72 69 74 20 69 6E 20 76 6F 6C 75 70 74 61 74 65 20 76 65 6C 69 74 20 65 73 73 65 20 63 69 6C 6C 75 6D 20 64 6F 6C 6F 72 65 20 65 75 20 66 75 67 69 61 74 20 6E 75 6C 6C 61 20 70 61 72 69 61 74 75 72 2E 20 45 78 63 65 70 74 65 75 72 20 73 69 6E 74 20 6F 63 63 61 65 63 61 74 20 63 75 70 69 64 61 74 61 74 20 6E 6F 6E 20 70 72 6F 69 64 65 6E 74 2C 20 73 75 6E 74 20 69 6E 20 63 75 6C 70 61 20 71 75 69 20 6F 66 66 69 63 69 61 20 64 65 73 65 72 75 6E 74 20 6D 6F 6C 6C 69 74 20 61 6E 69 6D 20 69 64 20 65 73 74 20 6C 61 62 6F 72 75 6D 2E

View File

@ -13,7 +13,6 @@ module eth_mac_test;
// Outputs
wire [11:0] mem_addr;
wire REF_CLK;
wire TXEN;
wire [1:0] TXD;
@ -25,32 +24,31 @@ module eth_mac_test;
.mem_data(mem_data),
.mem_addr(mem_addr),
.ctrl_word(ctrl_word),
.REF_CLK(REF_CLK),
.TXEN(TXEN),
.TXD(TXD)
);
always #2.5 clk <= ~clk;
always #10 clk <= ~clk;
reg run;
// memory
localparam MEM_SIZE = 26;
localparam MEM_SIZE = 445;
reg [7:0] mem [0:MEM_SIZE-1];
assign mem_data = mem[mem_addr];
// frame data
localparam FRAME_ADDR = 0;
localparam FRAME_LENGTH = 26;
localparam FRAME_LENGTH = 100;
localparam START = (1 << 31);
// RMII deserializer
integer wrt_cntr;
reg [7:0] deser;
always @(posedge REF_CLK)
always @(posedge clk)
begin
if (TXEN && run)
begin
deser = {deser[5:0], TXD};
deser = {TXD, deser[7:2]}; // right shift
wrt_cntr = wrt_cntr + 1;
if ((wrt_cntr & 32'b11) == 0)
begin
@ -72,7 +70,7 @@ module eth_mac_test;
run <= 0;
// populate memory
$readmemh("src/sim/eth_frame_mem.mem", mem);
$readmemh("src/sim/eth_large_frame_mem.mem", mem);
// Wait 20 ns for global reset to finish
#20;
@ -87,6 +85,8 @@ module eth_mac_test;
@(TXEN == 1);
ctrl_word <= 0;
@(TXEN == 0);
#20;

1
src/sim/fifo_out.txt Normal file
View File

@ -0,0 +1 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

1
src/sim/rmii_TXD.txt Normal file
View File

@ -0,0 +1 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

View File

@ -1,5 +1,8 @@
`timescale 1ns / 500ps
`include "src/rmii/rmii_transmit_controller.v"
`include "src/rmii/rmii_clock_generator.v"
module rmii_transmit_controller_test;
// Inputs
@ -8,9 +11,6 @@ module rmii_transmit_controller_test;
reg clear;
reg [7:0] data_in;
reg wrt;
wire REF_pulse;
wire REF_CLK;
wire REF_negpulse;
// Outputs
wire not_full;
@ -25,21 +25,12 @@ module rmii_transmit_controller_test;
.data_in(data_in),
.wrt(wrt),
.not_full(not_full),
.REF_pulse(REF_pulse),
.TXEN(TXEN),
.TXD(TXD)
.TXD(TXD),
.busy()
);
always #2.5 clk = ~clk;
rmii_clock_generator clk_gen(
.clk(clk),
.rst(rst),
.REF_CLK(REF_CLK),
.rising(REF_pulse),
.falling(REF_negpulse)
);
always #10 clk = ~clk;
integer ifile = 0, ofile = 0;
reg run;
@ -69,11 +60,11 @@ module rmii_transmit_controller_test;
integer wrt_cntr;
reg [7:0] deser;
always @(posedge REF_pulse)
always @(posedge clk)
begin
if (TXEN && run)
begin
deser = {deser[5:0], TXD};
deser = {TXD, deser[7:2]};
wrt_cntr = wrt_cntr + 1;
if ((wrt_cntr & 32'b11) == 0)
begin
@ -112,17 +103,22 @@ module rmii_transmit_controller_test;
$finish;
end
@(posedge clk);
@(posedge clk);
// start simulation
run <= 1;
read_input <= 1;
@(posedge clk);
// wait for the deassertion of run
@(TXEN == 1);
@(TXEN == 0);
run <= 0;
@(posedge REF_CLK);
@(posedge REF_CLK);
@(posedge clk);
@(posedge clk);
$fclose(ifile);
$fclose(ofile);

13
src/stream_mem_init.cgf Normal file
View File

@ -0,0 +1,13 @@
#version3.0
#memory_block_name=stream_init
#block_depth=4096
#data_width=8
#default_word=0
#default_pad_bit_value=0
#pad_direction=left
#data_radix=16
#address_radix=10
#coe_radix=MEMORY_INITIALIZATION_RADIX
#coe_data=MEMORY_INITIALIZATION_VECTOR
#data=
#end