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 `timescale 1ns / 1ps
//----------------------------------------------------------------------------- // THIS IS GENERATED VERILOG CODE.
// Copyright (C) 2009 OutputLogic.com // https://bues.ch/h/crcgen
// 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 // This code is Public Domain.
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED // Permission to use, copy, modify, and/or distribute this software for any
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. // purpose with or without fee is hereby granted.
//----------------------------------------------------------------------------- //
// 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; // 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( module crc32(
input wire clk, input wire clk,
input wire rst, input wire rst,
@ -22,52 +30,55 @@ module crc32(
output wire [31:0] crc_out 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 always @(posedge clk) 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 if(rst | clear) begin
lfsr_q <= {32{1'b0}}; result <= 32'hFFFFFFFF;
end end
else begin else begin
lfsr_q <= crc_en ? lfsr_c : lfsr_q; result <= crc_en ? crc(result, data_in) : result;
end end
end // always end // always
assign crc_out = ~result;
endmodule // crc32 endmodule // crc32

View File

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

View File

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

View File

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

View File

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

View File

@ -1,45 +1,80 @@
`timescale 1ns / 1ps `timescale 1ns / 1ps
`include "src/eth/eth_mac.v"
module jitmeas_top( module jitmeas_top(
input wire clk50M, // 50MHz clock input input clk50, rst, clear,
input wire rstbt,
//output wire clk200M input btn,
output wire [16:4] aio
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 [MEM_DATA_WIDTH-1:0] stream_mem_data;
wire main_pll_locked; wire [MEM_ADDR_WIDTH-1:0] stream_mem_addr;
wire clk200M;
MainPLL main_pll ( wire [31:0] ctrl_word;
// Clock in ports
.In_50MHz(clk50M), // IN
// Clock out ports eth_mac #(
.Out_200MHz(clk200M), // OUT .MEM_DATA_WIDTH(MEM_DATA_WIDTH),
.MEM_ADDR_WIDTH(MEM_ADDR_WIDTH)
// Status and control signals ) eth_mac_inst (
.RESET(rst), // IN .clk(clk50),
.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), .rst(rst),
.clear(1'b0),
.REF_CLK(REF_CLK), .mem_data(stream_mem_data),
.mem_addr(stream_mem_addr),
//.TXEN(TXEN), .ctrl_word(ctrl_word),
//.TXD(TXD),
.CRS_DV(0), .TXEN(TXEN),
.RXD(0) .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 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 parameter MAIN_CLK_FREQ = 200, // frequency of the main clock
// AUTOCALCULATED // AUTOCALCULATED
parameter CNTR_WIDTH = $clog2(MAIN_CLK_FREQ / 50), // width of the CNTR 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 parameter CNTR_MSB = CNTR_WIDTH - 1 // index of the counter's MSB
)( )(
input wire clk, // main clock input input wire clk, // main clock input
input wire rst, // synchronous reset input wire rst, // synchronous reset
output wire REF_CLK, // RMII REF_CLK output 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 rising // the next clk cycle comes with a rising edge on the REF_CLK
output wire falling // ... falling ... // output wire falling // ... falling ...
); );
reg [CNTR_MSB:0] ref_clk_cntr; reg [CNTR_MSB:0] ref_clk_cntr;
@ -20,18 +21,22 @@ always @(posedge clk)
begin begin
if (rst) if (rst)
begin begin
ref_clk_cntr = 0; ref_clk_cntr <= 0;
end end
else else
begin 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
end end
assign REF_CLK = ref_clk_cntr[CNTR_MSB]; assign REF_CLK = ref_clk_cntr;
assign rising = (&ref_clk_cntr[CNTR_MSB-1:0]) & (~ref_clk_cntr[CNTR_MSB]); assign rising = !ref_clk_cntr;
assign falling = &ref_clk_cntr;
endmodule endmodule

View File

@ -15,7 +15,9 @@ module rmii_serializer #(
output [SHIFT_SIZE-1:0] ser_out, // serialized output output [SHIFT_SIZE-1:0] ser_out, // serialized output
input shift, // enable shifting 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 // a combine reset or clear signal
@ -40,22 +42,36 @@ begin
if (load) // load the parallel data if (load) // load the parallel data
begin begin
shift_work <= par_in; 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 end
else if (shift) else if (shift)
begin begin
if (shift_count > 0) if (shift_count > 0)
begin 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 shift_work <= DIR ? (shift_work >> SHIFT_SIZE) : (shift_work << SHIFT_SIZE); // shift the contents of the work register
end end
end end
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 // 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 assign ser_out = DIR ? shift_work[SHIFT_SIZE-1:0] : shift_work[STORE_SIZE-1:STORE_SIZE-SHIFT_SIZE]; // serial output
endmodule endmodule

View File

@ -12,7 +12,6 @@ module rmii_transmit_controller #(
parameter SHIFT_COUNT = FIFO_DEPTH parameter SHIFT_COUNT = FIFO_DEPTH
)( )(
input clk, rst, clear, // general signals input clk, rst, clear, // general signals
input REF_pulse, // pulse that signals the coming rising edge on REF_CLK
/* FIFO signals */ /* FIFO signals */
input [STORAGE_MSB:0] data_in, // input data input [STORAGE_MSB:0] data_in, // input data
@ -23,15 +22,18 @@ module rmii_transmit_controller #(
output reg TXEN, // transmit enable output reg TXEN, // transmit enable
output [1:0] TXD, // transmit data 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 */ /* TX FIFO and its signals */
wire tx_fifo_empty; wire tx_fifo_empty;
wire tx_fifo_out_valid; wire tx_fifo_out_valid;
wire tx_fifo_full; wire tx_fifo_full;
wire [STORAGE_WIDTH-1:0]tx_fifo_out; 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 #( fifo #(
.DEPTH(FIFO_DEPTH), .DEPTH(FIFO_DEPTH),
@ -58,26 +60,31 @@ assign not_full = !tx_fifo_full;
wire oser_load = tx_fifo_out_valid; wire oser_load = tx_fifo_out_valid;
wire oser_empty; wire oser_empty;
//wire oser_exhausted;
wire oser_single;
wire [1:0] oser_out;
rmii_serializer #( rmii_serializer #(
.STORE_SIZE(STORAGE_WIDTH), .STORE_SIZE(STORAGE_WIDTH),
.DIR(0) // LEFT .DIR(1) // RIGHT
) out_serializer ( ) out_serializer (
.clk(clk), .clk(clk),
.rst(rst), .rst(rst),
.clear(clear), .clear(clear),
.par_in(tx_fifo_out), .par_in(tx_fifo_out),
.ser_out(TXD), .ser_out(oser_out),
.load(oser_load), .load(oser_load),
.shift(REF_pulse), .shift(1'b1),
.empty(oser_empty) .single(oser_single),
.empty(oser_empty),
.exhausted(/*oser_exhausted*/)
); );
/* TXEN control */ /* TXEN control */
always @(posedge clk) always @(posedge clk)
begin begin
if (rst | clear) if (rstclr)
begin begin
TXEN <= 0; TXEN <= 0;
end end
@ -87,13 +94,35 @@ begin
begin begin
TXEN <= 1; TXEN <= 1;
end 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 begin
TXEN <= 0; TXEN <= 0;
end end
end 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 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 // Outputs
wire [11:0] mem_addr; wire [11:0] mem_addr;
wire REF_CLK;
wire TXEN; wire TXEN;
wire [1:0] TXD; wire [1:0] TXD;
@ -25,32 +24,31 @@ module eth_mac_test;
.mem_data(mem_data), .mem_data(mem_data),
.mem_addr(mem_addr), .mem_addr(mem_addr),
.ctrl_word(ctrl_word), .ctrl_word(ctrl_word),
.REF_CLK(REF_CLK),
.TXEN(TXEN), .TXEN(TXEN),
.TXD(TXD) .TXD(TXD)
); );
always #2.5 clk <= ~clk; always #10 clk <= ~clk;
reg run; reg run;
// memory // memory
localparam MEM_SIZE = 26; localparam MEM_SIZE = 445;
reg [7:0] mem [0:MEM_SIZE-1]; reg [7:0] mem [0:MEM_SIZE-1];
assign mem_data = mem[mem_addr]; assign mem_data = mem[mem_addr];
// frame data // frame data
localparam FRAME_ADDR = 0; localparam FRAME_ADDR = 0;
localparam FRAME_LENGTH = 26; localparam FRAME_LENGTH = 100;
localparam START = (1 << 31); localparam START = (1 << 31);
// RMII deserializer // RMII deserializer
integer wrt_cntr; integer wrt_cntr;
reg [7:0] deser; reg [7:0] deser;
always @(posedge REF_CLK) always @(posedge clk)
begin begin
if (TXEN && run) if (TXEN && run)
begin begin
deser = {deser[5:0], TXD}; deser = {TXD, deser[7:2]}; // right shift
wrt_cntr = wrt_cntr + 1; wrt_cntr = wrt_cntr + 1;
if ((wrt_cntr & 32'b11) == 0) if ((wrt_cntr & 32'b11) == 0)
begin begin
@ -72,7 +70,7 @@ module eth_mac_test;
run <= 0; run <= 0;
// populate memory // 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 // Wait 20 ns for global reset to finish
#20; #20;
@ -87,6 +85,8 @@ module eth_mac_test;
@(TXEN == 1); @(TXEN == 1);
ctrl_word <= 0;
@(TXEN == 0); @(TXEN == 0);
#20; #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 `timescale 1ns / 500ps
`include "src/rmii/rmii_transmit_controller.v"
`include "src/rmii/rmii_clock_generator.v"
module rmii_transmit_controller_test; module rmii_transmit_controller_test;
// Inputs // Inputs
@ -8,9 +11,6 @@ module rmii_transmit_controller_test;
reg clear; reg clear;
reg [7:0] data_in; reg [7:0] data_in;
reg wrt; reg wrt;
wire REF_pulse;
wire REF_CLK;
wire REF_negpulse;
// Outputs // Outputs
wire not_full; wire not_full;
@ -25,21 +25,12 @@ module rmii_transmit_controller_test;
.data_in(data_in), .data_in(data_in),
.wrt(wrt), .wrt(wrt),
.not_full(not_full), .not_full(not_full),
.REF_pulse(REF_pulse),
.TXEN(TXEN), .TXEN(TXEN),
.TXD(TXD) .TXD(TXD),
.busy()
); );
always #2.5 clk = ~clk; always #10 clk = ~clk;
rmii_clock_generator clk_gen(
.clk(clk),
.rst(rst),
.REF_CLK(REF_CLK),
.rising(REF_pulse),
.falling(REF_negpulse)
);
integer ifile = 0, ofile = 0; integer ifile = 0, ofile = 0;
reg run; reg run;
@ -69,11 +60,11 @@ module rmii_transmit_controller_test;
integer wrt_cntr; integer wrt_cntr;
reg [7:0] deser; reg [7:0] deser;
always @(posedge REF_pulse) always @(posedge clk)
begin begin
if (TXEN && run) if (TXEN && run)
begin begin
deser = {deser[5:0], TXD}; deser = {TXD, deser[7:2]};
wrt_cntr = wrt_cntr + 1; wrt_cntr = wrt_cntr + 1;
if ((wrt_cntr & 32'b11) == 0) if ((wrt_cntr & 32'b11) == 0)
begin begin
@ -112,17 +103,22 @@ module rmii_transmit_controller_test;
$finish; $finish;
end end
@(posedge clk);
@(posedge clk);
// start simulation // start simulation
run <= 1; run <= 1;
read_input <= 1; read_input <= 1;
@(posedge clk);
// wait for the deassertion of run // wait for the deassertion of run
@(TXEN == 1); @(TXEN == 1);
@(TXEN == 0); @(TXEN == 0);
run <= 0; run <= 0;
@(posedge REF_CLK); @(posedge clk);
@(posedge REF_CLK); @(posedge clk);
$fclose(ifile); $fclose(ifile);
$fclose(ofile); $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