/*! * Module:dct1d_chen_reorder_out * @file dct1d_chen_reorder_out.v * @date 2016-06-08 * @author Andrey Filippov * * @brief Reorder data from dct1d_chen output to natural sequence * * @copyright Copyright (c) 2016 Elphel, Inc. * * License: * *dct1d_chen_reorder_out.v is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * dct1d_chen_reorder_out.v is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Additional permission under GNU GPL version 3 section 7: * If you modify this Program, or any covered work, by linking or combining it * with independent modules provided by the FPGA vendor only (this permission * does not extend to any 3-rd party modules, "soft cores" or macros) under * different license terms solely for the purpose of generating binary "bitstream" * files and/or simulating the code, the copyright holders of this Program give * you the right to distribute the covered work without those independent modules * as long as the source code for them is available from the FPGA vendor free of * charge, and there is no dependence on any encrypted modules for simulating of * the combined code. This permission applies to you if the distributed code * contains all the components and scripts required to completely simulate it * with at least one of the Free Software programs. */ `timescale 1ns/1ps module dct1d_chen_reorder_out#( parameter WIDTH = 24 )( input clk, input rst, input en, // sampled at timeslot of pre2_start input [WIDTH -1:0] din, // pre2_start-X-F4-X-F2-X-F6-F5-F0-F3-X-F1-X-F7 input pre2_start, // Two cycles ahead of F4 output [WIDTH -1:0] dout, // data in natural order: F0-F1-F2-F3-F4-F5-F6-F7 output start_out, // 1 ahead of the first F0 output reg dv, // output data valid output en_out // to be sampled when start_out is expected ); reg [WIDTH -1:0] reord_buf_ram[0:15]; reg [WIDTH -1:0] dout_r; reg [3:0] cntr_in; reg pre_we_r; reg we_r; reg [3:0] ina_rom; wire [3:0] waddr = {ina_rom[3] ^ cntr_in[3], ina_rom[2:0]}; reg [3:0] raddr; reg [2:0] per_type; // idle/last:0, first cycle - 1, 2-nd - 2, other - 3,... ~en->6 ->7 -> 0 (to generate pre2_start_out) reg start_out_r; reg en_out_r; wire stop_out; // qualify with en assign dout = dout_r; assign start_out = start_out_r; assign en_out = en_out_r; always @(posedge clk) begin if (rst) per_type <= 0; else if (pre2_start) per_type <= 3'h1; else if (&cntr_in[2:0]) begin if (!per_type[2] && !en) per_type <= 3'h6; else if ((per_type != 0) && (per_type != 3)) per_type <= per_type + 1; end if (rst) pre_we_r <= 0; else if (pre2_start) pre_we_r <= 1; else if ((per_type == 0) || ((cntr_in==3) && per_type[2])) pre_we_r <= 0; we_r <= pre_we_r; if (rst) cntr_in <= 0; else if (pre2_start) cntr_in <= {~cntr_in[3],3'b0}; else if (pre_we_r) cntr_in <= cntr_in + 1; case (cntr_in[2:0]) 3'h0: ina_rom <= {1'b0,3'h4}; 3'h1: ina_rom <= {1'b1,3'h1}; 3'h2: ina_rom <= {1'b0,3'h2}; 3'h3: ina_rom <= {1'b1,3'h7}; 3'h4: ina_rom <= {1'b0,3'h6}; 3'h5: ina_rom <= {1'b0,3'h5}; 3'h6: ina_rom <= {1'b0,3'h0}; 3'h7: ina_rom <= {1'b1,3'h3}; endcase if (we_r) reord_buf_ram[waddr] <= din; if ((per_type == 2) && (cntr_in == 1)) raddr <= {~cntr_in[3], 3'b0}; else if ((raddr[2:0] != 0) || (per_type !=0)) raddr <= raddr + 1; if (en_out_r) dout_r <= reord_buf_ram[raddr]; start_out_r <= (per_type == 2) && (cntr_in == 1); if (rst ||(per_type == 0) ) en_out_r <= 0; // else if (cntr_in == 1) en_out_r <= (per_type == 2) || !per_type[2]; else if ((cntr_in == 1) && (per_type == 2)) en_out_r <= 1; else if (stop_out && !en) en_out_r <= 0; //stop_out dv <= en_out_r; // if (rst) dv <= 0; // else if (start_out_r) dv <= 1; // else if ((raddr[2:0] == 0) && !en_out_r) dv <= 0; end dly01_16 dly01_16_i ( .clk (clk), // input .rst (rst), // input .dly (4'd8), // input[3:0] .din ((&cntr_in[2:0]) && !en), // input .dout (stop_out) // output ); endmodule