/* * DSI Core * Copyright (C) 2013 twl * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. */ `timescale 1ns/1ps /* * dsi_packer.v * * A module that tightly packs bytes or byte sequences in to an output word of certain * size. */ module dsi_byte_reverse ( d_i, q_o); parameter g_num_bytes = 4; input [g_num_bytes * 8 - 1 : 0] d_i; output [g_num_bytes * 8 - 1 : 0] q_o; generate genvar i, j; for(i=0;i<8;i=i+1) for(j=0;j g_output_bytes ? g_input_bytes : g_output_bytes) + 2; input clk_i, rst_n_i; input [g_input_bytes * 8 - 1 : 0] d_i; input [3 : 0] d_size_i; output d_req_o; input d_valid_i, q_flush_i; output [g_output_bytes * 8 -1 :0] q_o; output reg [g_output_bytes-1:0] q_valid_o; output d_empty_o; input q_req_i; wire [g_input_bytes * 8 - 1 : 0] d_in; reg [g_output_bytes * 8 - 1 : 0] q_out; reg [4:0] count, avail, avail_next; reg [c_shiftreg_bytes * 8 -1 :0] shreg; wire [c_shiftreg_bytes * 8 -1 :0] in_shifted; wire shift_out; wire [4:0] in_shift; wire d_req_int; assign shift_out = (count >= g_output_bytes && q_req_i); assign in_shift = (shift_out ? count - g_output_bytes : count); dsi_byte_swapper #(g_input_bytes) U_RevIn ( d_i, d_size_i, d_in ); dsi_byte_reverse #(g_output_bytes) U_RevOut ( q_out, q_o ); dsi_byte_shifter #( .g_data_bytes(g_input_bytes), .g_max_shift(c_shiftreg_bytes - 1) ) U_Shifter ( .d_i(d_in), .shift_i(in_shift), .shifted_o(in_shifted) ); always@(posedge clk_i) if(!rst_n_i) begin q_valid_o <= 0; q_out <= 0; end else if(shift_out || q_flush_i) begin : drive_output integer i; q_out <= shreg[g_output_bytes * 8 - 1 : 0]; for(i=0;i i; end else q_valid_o <= 0; always@(posedge clk_i) if (!rst_n_i) begin count <= 0; avail <= c_shiftreg_bytes; shreg <= 0; end else begin if(d_valid_i && shift_out) begin shreg <= (shreg >> ( 8 * g_output_bytes )) | in_shifted; count <= count - g_output_bytes + d_size_i; end else if(d_valid_i) begin shreg <= shreg | in_shifted; count <= count + d_size_i; end else if(shift_out) begin shreg <= (shreg >> ( 8 * g_output_bytes )); count <= count - g_output_bytes; end else if (q_flush_i) begin count <= 0; shreg <= 0; end avail <= avail_next; end // else: !if(!rst_n_i) always@* if(d_valid_i && shift_out) avail_next <= avail + g_output_bytes - d_size_i; else if(d_valid_i) avail_next <= avail - d_size_i; else if(shift_out) avail_next <= avail + g_output_bytes; else if(q_flush_i) avail_next <= c_shiftreg_bytes; else avail_next <= avail; assign d_req_int = (avail_next >= g_input_bytes) || (shift_out && avail_next >= (g_input_bytes - g_output_bytes)); assign d_req_o = d_req_int; assign d_empty_o = !count; endmodule // dsi_packer