dsi-shield/hdl/rtl/dsi_core/dsi_utils.v

110 lines
3.8 KiB
Verilog

/*
* DSI Core
* Copyright (C) 2013 twl <twlostow@printf.cc>
*
* 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_utils.v
*
* Some utility stuff (parity/CRC generators)
*/
module dsi_parity
(
input [23:0] d_i,
output [7:0] p_o
);
assign p_o[0]=^{d_i[2:0], d_i[5:4], d_i[7], d_i[11:10], d_i[13], d_i[16], d_i[23:20]};
assign p_o[1]=^{d_i[1:0], d_i[4:3], d_i[6], d_i[8], d_i[10], d_i[12], d_i[14], d_i[17], d_i[23:20]};
assign p_o[2]=^{d_i[0], d_i[3:2], d_i[6:5], d_i[9], d_i[12:11], d_i[15], d_i[18], d_i[22:20] };
assign p_o[3]=^{d_i[3:1], d_i[9:7], d_i[15:13], d_i[21:19], d_i[23]};
assign p_o[4]=^{d_i[9:4], d_i[20:16], d_i[23:22]};
assign p_o[5]=^{d_i[19:10], d_i[23:21]};
assign p_o[7:6]=2'b0;
endmodule // dsi_parity
module dsi_crc_comb (input[15:0] crc, input[7:0] x, output [15:0] crc_new);
assign crc_new[0] = crc[8] ^ crc[12] ^ x[7-0] ^ x[7-4];
assign crc_new[1] = crc[9] ^ crc[13] ^ x[7-1] ^ x[7-5];
assign crc_new[2] = crc[10] ^ crc[14] ^ x[7-2] ^ x[7-6];
assign crc_new[3] = crc[11] ^ crc[15] ^ x[7-3] ^ x[7-7];
assign crc_new[4] = crc[12] ^ x[7-4];
assign crc_new[5] = crc[8] ^ crc[12] ^ crc[13] ^ x[7-0] ^ x[7-4] ^ x[7-5];
assign crc_new[6] = crc[9] ^ crc[13] ^ crc[14] ^ x[7-1] ^ x[7-5] ^ x[7-6];
assign crc_new[7] = crc[10] ^ crc[14] ^ crc[15] ^ x[7-2] ^ x[7-6] ^ x[7-7];
assign crc_new[8] = crc[0] ^ crc[11] ^ crc[15] ^ x[7-3] ^ x[7-7];
assign crc_new[9] = crc[1] ^ crc[12] ^ x[7-4];
assign crc_new[10] = crc[2] ^ crc[13] ^ x[7-5];
assign crc_new[11] = crc[3] ^ crc[14] ^ x[7-6];
assign crc_new[12] = crc[4] ^ crc[8] ^ crc[12] ^ crc[15] ^ x[7-0] ^ x[7-4] ^ x[7-7];
assign crc_new[13] = crc[5] ^ crc[9] ^ crc[13] ^ x[7-1] ^ x[7-5];
assign crc_new[14] = crc[6] ^ crc[10] ^ crc[14] ^ x[7-2] ^ x[7-6];
assign crc_new[15] = crc[7] ^ crc[11] ^ crc[15] ^ x[7-3] ^ x[7-7];
endmodule // dsi_crc_comb
module dsi_crc
(
clk_i,
rst_i,
valid_i,
nbytes_i,
d_i,
crc_o);
parameter g_max_data_bytes = 3;
input [g_max_data_bytes*8-1:0] d_i;
input valid_i;
input [2:0] nbytes_i;
input clk_i;
input rst_i;
output [15:0] crc_o;
reg [15:0] crc_cur;
wire [15:0] stages_in [0:g_max_data_bytes-1];
wire [15:0] stages_out [0:g_max_data_bytes-1];
generate
genvar i ;
for(i=0;i<g_max_data_bytes;i=i+1)
begin
if(i != g_max_data_bytes-1)
assign stages_in[i] = (nbytes_i == (i+1) ? crc_cur : stages_out[i+1]);
dsi_crc_comb stageX(stages_in[i], d_i[8*i+7:8*i], stages_out[i]);
end
assign stages_in[g_max_data_bytes-1] = crc_cur;
endgenerate
always@(posedge clk_i)
if(rst_i)
crc_cur <= 16'hffff;
else if(valid_i)
crc_cur <= stages_out[0];
assign crc_o = {crc_cur[0], crc_cur[1],crc_cur[2], crc_cur[3],
crc_cur[4], crc_cur[5],crc_cur[6], crc_cur[7],
crc_cur[8], crc_cur[9],crc_cur[10], crc_cur[11],
crc_cur[12], crc_cur[13],crc_cur[14], crc_cur[15]};
endmodule // dsi_crc