Last active
April 8, 2020 21:15
-
-
Save rschlaikjer/f4e7bc616b28880a33c127ea6833a6f8 to your computer and use it in GitHub Desktop.
Output DDR sample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`default_nettype none | |
`define CLK_HZ 25_000_000 | |
module top( | |
// 25MHz ref clock | |
input CLK_25M, | |
// Green indicator LED (open drain) | |
output DATA_LED, | |
// Debug lines | |
output wire J1_R0, | |
output wire J1_R1, | |
output wire J1_G0, | |
output wire J1_G1, | |
output wire J1_B0, | |
output wire J1_B1 | |
); | |
wire clk = CLK_25M; | |
// Reset counter, don't start til the PLL is locked | |
reg [4:0] reset_counter = 0; | |
wire g_reset = reset_counter != 31; | |
always @(posedge CLK_25M) | |
if (reset_counter < 31) | |
reset_counter <= reset_counter + 1; | |
// Test data to send | |
reg [7:0] data [256]; | |
integer j; | |
initial begin | |
for (j = 0; j < 255; j = j + 1) begin | |
data[j] = j; | |
end | |
end | |
// DDR clock | |
wire ddr_clk; | |
ODDRX1F ddr_clk_inst( | |
.SCLK(clk), | |
.RST(g_reset), | |
.D0(1'b1), | |
.D1(1'b0), | |
.Q(ddr_clk) | |
); | |
DELAYF #( | |
.DEL_MODE("USER_DEFINED"), | |
.DEL_VALUE(80) | |
) delay_inst ( | |
.LOADN(1'd1), | |
.MOVE(1'd0), | |
.DIRECTION(1'd0), | |
.A(ddr_clk), | |
.Z(J1_R0) | |
); | |
// Data DDR output | |
reg [7:0] i_ddr_data; | |
wire [3:0] data_lines = {J1_B0, J1_R1, J1_G1, J1_B1}; | |
wire [3:0] o_ddr_data = data_lines; | |
genvar i; | |
generate | |
for (i = 0; i < 4; i = i + 1) begin | |
ODDRX1F ddr_inst( | |
.SCLK(clk), | |
.RST(g_reset), | |
.D0(i_ddr_data[i]), | |
.D1(i_ddr_data[i+4]), | |
.Q(o_ddr_data[i]) | |
); | |
end | |
endgenerate | |
// Every time our trigger_send line is pulsed, transmit 32 bytes of data | |
// from our buffer over the 1x geared ODDR block above | |
reg trigger_send = 0; | |
reg tx_enable = 0; | |
assign J1_G0 = tx_enable; | |
reg [7:0] bytes_to_send = 0; | |
reg [7:0] tx_offset = 0; | |
always @(posedge clk) begin | |
if (bytes_to_send > 0) begin | |
i_ddr_data = data[tx_offset]; | |
tx_offset <= tx_offset + 1; | |
bytes_to_send <= bytes_to_send - 1; | |
tx_enable <= 1; | |
end else begin | |
i_ddr_data <= 0; | |
tx_enable <= 0; | |
if (trigger_send) begin | |
bytes_to_send <= 32; | |
tx_offset <= 0; | |
end | |
end | |
end | |
// Blink the status LED for each transmission | |
reg led = 0; | |
assign DATA_LED = led; | |
// Twice a second, trigger a DDR transmission | |
localparam PRESCALER = (`CLK_HZ / 2) - 1; | |
reg [$clog2(PRESCALER):0] prescaler = 0; | |
always @(posedge clk) begin | |
if (prescaler == 0) begin | |
prescaler <= PRESCALER; | |
trigger_send <= 1; | |
led <= ~led; | |
end else | |
trigger_send <= 0; | |
prescaler <= prescaler - 1; | |
end | |
endmodule // top |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment