aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/rfnoc/fosphor/f15_eoseq.v
blob: 6d209cd16668676d7569f4e2f9795916a4c87904 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
 * f15_eoseq.v
 *
 * Resequence a data flow with data/valid/last ensuring EVEN/ODD
 * sequencing (even data on even cycles, odd data on odd cycles)
 *
 * Copyright (C) 2014  Ettus Corporation LLC
 * Copyright 2018 Ettus Research, a National Instruments Company
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 *
 * vim: ts=4 sw=4
 */

`ifdef SIM
`default_nettype none
`endif

module f15_eoseq #(
	parameter integer WIDTH = 16
)(
	input  wire [WIDTH-1:0] in_data,
	input  wire in_valid,
	input  wire in_last,
	output reg  [WIDTH-1:0] out_data,
	output reg  out_valid,
	output reg  out_last,
	input  wire clk,
	input  wire rst
);

	// Signals
	reg [WIDTH-1:0] buf_data;
	reg buf_valid;
	reg buf_last;

	wire flip;
	reg odd;
	reg sel;

	// Control
	always @(posedge clk)
		if (rst)
			odd <= 1'b0;
		else
			odd <= ~(in_last & in_valid) & (odd ^ in_valid);

	always @(posedge clk)
		if (rst)
			sel <= 1'b0;
		else if (flip)
			sel <= ~sel;

	assign flip = ~in_valid | (in_last & ~odd);

	// Buffer
	always @(posedge clk)
	begin
		buf_data  <= in_data;
		buf_valid <= in_valid;
		buf_last  <= in_last;
	end

	// Output
	always @(posedge clk)
	begin
		if (sel) begin
			out_data  <= buf_data;
			out_valid <= buf_valid;
			out_last  <= buf_last;
		end else begin
			out_data  <= in_data;
			out_valid <= in_valid;
			out_last  <= in_last;
		end
	end

endmodule // f15_eoseq