├── CRC-16-parallel.v ├── CRC_16_parallel_test.v ├── CRC_16_serial.v ├── CRC_16_serial_test.v ├── CRC_32_paraller.v ├── CRC_32_paraller_test.v └── README.md /CRC-16-parallel.v: -------------------------------------------------------------------------------- 1 | 2 | module CRC_16_paraller(clk,rst,load,d_finish,crc_in,crc_out); 3 | input clk; 4 | input rst; 5 | input load; 6 | input d_finish; 7 | input [7:0] crc_in; 8 | output [7:0] crc_out; 9 | reg [7:0] crc_out; 10 | reg [15:0] crc_reg; 11 | reg [1:0] count; 12 | reg [1:0] state; 13 | wire [15:0] next_crc_reg; // 14 | parameter idle = 2'b00; // 15 | parameter compute = 2'b01;// 16 | parameter finish = 2'b10; // 17 | // 18 | assign next_crc_reg[0] = (^crc_in[7:0]) ^ (^crc_reg[15:8]); 19 | assign next_crc_reg[1] = (^crc_in[6:0]) ^ (^crc_reg[15:9]); 20 | assign next_crc_reg[2] = crc_in[7] ^ crc_in[6] ^ crc_reg[9] ^ crc_reg[8]; 21 | assign next_crc_reg[3] = crc_in[6] ^ crc_in[5] ^ crc_reg[10] ^ 22 | crc_reg[9]; 23 | assign next_crc_reg[4] = crc_in[5] ^ crc_in[4] ^ crc_reg[11] ^ 24 | crc_reg[10]; 25 | assign next_crc_reg[5] = crc_in[4] ^ crc_in[3] ^ crc_reg[12] ^ 26 | crc_reg[11]; 27 | assign next_crc_reg[6] = crc_in[3] ^ crc_in[2] ^ crc_reg[13] ^ 28 | crc_reg[12]; 29 | assign next_crc_reg[7] = crc_in[2] ^ crc_in[1] ^ crc_reg[14] ^ 30 | crc_reg[13]; 31 | assign next_crc_reg[8] = crc_in[1] ^ crc_in[0] ^ crc_reg[15] ^ crc_reg[14] 32 | ^ crc_reg[0]; 33 | assign next_crc_reg[9] = crc_in[0] ^ crc_reg[15] ^ crc_reg[1]; 34 | assign next_crc_reg[14:10] = crc_reg[6:2]; 35 | assign next_crc_reg[15] = (^crc_in[7:0]) ^ (^crc_reg[15:7]); 36 | always@(posedge clk) //؂྽ clk ҅ጔ᝻ว൩୺Չ 37 | begin 38 | case(state) // 39 | idle:begin // 40 | if(load) // 41 | state <= compute; 42 | else 43 | state <= idle; 44 | end 45 | compute:begin 46 | if(d_finish)// 47 | state <= finish; 48 | else 49 | state <= compute; 50 | end 51 | finish:begin 52 | if(count==2)// 53 | state <= idle; 54 | else 55 | state <= finish; 56 | end 57 | endcase 58 | end 59 | always@(posedge clk or negedge rst)// 60 | if(rst) 61 | begin 62 | crc_reg[15:0] <= 16'b0000_0000_0000_0000;// 63 | state <= idle; 64 | count <= 2'b00; 65 | end 66 | else 67 | case(state) 68 | idle:begin // 69 | crc_reg[15:0] <= 16'b0000_0000_0000_0000; 70 | end 71 | compute:begin // 72 | crc_reg[15:0]<= next_crc_reg[15:0]; 73 | crc_out[7:0] <= crc_in[7:0]; 74 | end 75 | finish:begin // 76 | crc_reg[15:0] <= {crc_reg[7:0],8'b0000_0000}; 77 | crc_out[7:0] <= crc_reg[15:8]; 78 | end 79 | endcase 80 | endmodule 81 | -------------------------------------------------------------------------------- /CRC_16_parallel_test.v: -------------------------------------------------------------------------------- 1 | // 2 | module CRC_16_parallel_test; 3 | reg clk; 4 | reg rst; 5 | reg load; 6 | reg d_finish; 7 | reg [7:0] crc_in; 8 | wire [7:0] crc_out; 9 | parameter clk_period = 40; 10 | 11 | initial 12 | begin 13 | #clk_period clk = 1; 14 | #clk_period rst = 1; 15 | #clk_period rst = 0; 16 | #clk_period crc_in[7:0] = 8'b1010_1010; // 17 | #clk_period load = 1; 18 | #clk_period load = 0; 19 | #clk_period d_finish = 0; 20 | #(10*clk_period) d_finish = 1; 21 | #clk_period d_finish = 0; 22 | end 23 | always #(clk_period/2) clk = ~clk; 24 | always #(clk_period) crc_in[7:0] = ~crc_in[7:0]; // 25 | // 26 | CRC_16_paraller 27 | u1(.clk(clk), .rst(rst), .load(load), .d_finish(d_finish), .crc_in(crc_in), .crc_out(crc_out)); 28 | endmodule 29 | -------------------------------------------------------------------------------- /CRC_16_serial.v: -------------------------------------------------------------------------------- 1 | //模組的宣告,CRC_16_serial 2 | //模組功能:該模組是 crc-16 校驗碼的編碼電路,該電路採用串列線性移位暫存器 3 | module CRC_16_serial(clk,rst,load,d_finish,crc_in,crc_out); 4 | input clk; //輸入信號 5 | input rst; //重設信號 6 | input load; //開始編碼信號 7 | input d_finish; //編碼結束信號 8 | input crc_in; //待編碼字輸入 9 | output crc_out; //編碼後碼字輸出 10 | reg crc_out; //碼字輸出暫存器,1bit 11 | reg [15:0] crc_reg; //線性移位暫存器,16bit 12 | reg [1:0] state; //狀態暫存器,2bit 13 | reg [4:0] count; //計數暫存器,5bit 14 | parameter idle = 2'b00; //等待狀態 15 | parameter compute = 2'b01;//計算狀態 16 | parameter finish = 2'b10; //計算結束狀態 17 | always@(posedge clk) //在每次 clk 為正緣觸發時執行 18 | begin //可看成 c 語言裡的上括弧,end 則可看成下括弧 19 | case(state) //以 state 來選擇 case 20 | idle:begin //是等待狀態 21 | if(load) //load 信號有效進入 compute 狀態 22 | state <= compute; 23 | else 24 | state <= idle; 25 | end 26 | compute:begin //d_finish 信號有效進入 finish 狀態 27 | if(d_finish) 28 | state <= finish; 29 | else 30 | state <= compute; 31 | end 32 | finish:begin //判斷是否 16 個暫存器中的資料都完全輸出 33 | if(count==16) 34 | state <= idle; 35 | else 36 | count <= count+1; 37 | end 38 | endcase 39 | end 40 | always@(posedge clk or negedge rst)//每當 clk 正緣觸發或是 rst 負緣觸發就執行 41 | if(rst) 42 | begin 43 | crc_reg[15:0] <= 16'b0000_0000_0000_0000;//暫存器預裝初值 44 | count <= 5'b0_0000; 45 | state <= idle; 46 | end 47 | else 48 | case(state) 49 | idle:begin 50 | crc_reg[15:0] <= 16'b0000_0000_0000_0000; 51 | end 52 | compute:begin 53 | //產生多項式 x^16+x^15+x^2+1 54 | crc_reg[0] <= crc_reg[15] ^ crc_in; 55 | crc_reg[1] <= crc_reg[0]; 56 | crc_reg[2] <= crc_reg[1] ^ crc_reg[15] ^ crc_in; 57 | crc_reg[14:3] <= crc_reg[13:2]; 58 | crc_reg[15] <= crc_reg[14] ^ crc_reg[15] ^ crc_in; 59 | crc_out <= crc_in; //輸入作為輸出 60 | end 61 | finish:begin 62 | crc_out <= crc_reg[15]; //暫存器 15 作為輸出 63 | crc_reg[15:0] <= {crc_reg[14:0],1'b0}; //移位 64 | end 65 | endcase 66 | endmodule 67 | -------------------------------------------------------------------------------- /CRC_16_serial_test.v: -------------------------------------------------------------------------------- 1 | //模組 CRC-16-test 2 | //模組功能:該模組是 crc16 校驗碼串列編碼電路, 3 | //該編碼電路可將串列輸入的資料進行編碼 4 | module CRC_16_serial_test; 5 | reg clk; 6 | reg rst; 7 | reg load; 8 | reg d_finish; 9 | reg crc_in; 10 | wire crc_out;//線網型資料,1bit 11 | parameter clk_period = 40; //clk 週期為 40ns 12 | initial //初始化相關阜值 13 | begin 14 | #clk_period clk = 1; 15 | #clk_period rst = 1; 16 | #clk_period rst = 0; 17 | #clk_period crc_in = 1; //輸入待編碼資料 18 | #clk_period load = 1; 19 | #clk_period load = 0; 20 | #clk_period d_finish = 0; 21 | #(80*clk_period) d_finish = 1; 22 | #clk_period d_finish = 0; 23 | end 24 | always #(clk_period/2) clk = ~clk; //每 20ns 換電位 25 | always #(2*clk_period) crc_in = ~crc_in;//每 80ns 更換待編碼字輸入電位 26 | 27 | //調用串列編碼模組 28 | CRC_16_serial 29 | u1(.clk(clk), .rst(rst), .load(load), .d_finish(d_finish), .crc_in(crc_in), .crc_out(crc_out)); 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /CRC_32_paraller.v: -------------------------------------------------------------------------------- 1 | // 2 | module CRC_32_paraller(clk,rst,load,d_finish,crc_in,crc_out); 3 | input clk; // 4 | input rst; // 5 | input load; // 6 | input d_finish; // 7 | input [7:0] crc_in; // 8 | output [7:0] crc_out; // 9 | reg [7:0] crc_out; // 10 | reg [31:0] crc_reg; // 11 | reg [1:0] count; // 12 | reg [1:0] state; // 13 | wire [31:0] next_crc_reg; // 14 | parameter idle = 2'b00; // 15 | parameter compute = 2'b01; // 16 | parameter finish = 2'b10; // 17 | // 18 | assign next_crc_reg[0] = crc_reg[24] ^ crc_reg[30] ^ crc_in[0] ^ 19 | crc_in[6]; 20 | assign next_crc_reg[1] = crc_reg[24] ^ crc_reg[25] ^ crc_reg[30] ^ 21 | crc_reg[31] ^ crc_in[0] ^ crc_in[1] ^ crc_in[6] ^ crc_in[7]; 22 | assign next_crc_reg[2] = crc_reg[24] ^ crc_reg[25] ^ crc_reg[26] ^ 23 | crc_reg[30] ^ crc_reg[31] ^ crc_in[0] ^ crc_in[1] ^ crc_in[2] ^ crc_in[6] 24 | ^ crc_in[7]; 25 | assign next_crc_reg[3] = crc_reg[25] ^ crc_reg[26] ^ crc_reg[27] ^ 26 | crc_reg[31] ^ crc_in[1] ^ crc_in[2] ^ crc_in[3] ^ crc_in[7]; 27 | assign next_crc_reg[4] = crc_reg[24] ^ crc_reg[26] ^ crc_reg[27] ^ 28 | crc_reg[28] ^ crc_reg[30] ^ crc_in[0] ^ crc_in[2] ^ crc_in[3] ^ crc_in[4] 29 | ^ crc_in[6]; 30 | assign next_crc_reg[5] = crc_reg[24] ^ crc_reg[25] ^ crc_reg[27] ^ 31 | crc_reg[28] ^ crc_reg[29] ^ crc_reg[30] ^ crc_reg[31] ^ crc_in[0] ^ 32 | crc_in[1] ^ crc_in[3] ^ crc_in[4] ^ crc_in[5] ^ crc_in[6] ^ crc_in[7]; 33 | assign next_crc_reg[6] = crc_reg[25] ^ crc_reg[26] ^ crc_reg[28] ^ 34 | crc_reg[29] ^ crc_reg[30] ^ crc_reg[31] ^ crc_in[1] ^ crc_in[2] ^ crc_in[4] 35 | ^ crc_in[5] ^ crc_in[6] ^ crc_in[7]; 36 | assign next_crc_reg[7] = crc_reg[24] ^ crc_reg[26] ^ crc_reg[27] ^ 37 | crc_reg[29] ^ crc_reg[31] ^ crc_in[0] ^ crc_in[2] ^ crc_in[3] ^ crc_in[5] 38 | ^ crc_in[7]; 39 | assign next_crc_reg[8] = crc_reg[0] ^ crc_reg[24] ^ crc_reg[25] ^ 40 | crc_reg[27] ^ crc_reg[28] ^ crc_in[0] ^ crc_in[1] ^ crc_in[3] ^ crc_in[4]; 41 | assign next_crc_reg[9] = crc_reg[1] ^ crc_reg[25] ^ crc_reg[26] ^ 42 | crc_reg[28] ^ crc_reg[29] ^ crc_in[1] ^ crc_in[2] ^ crc_in[4] ^ crc_in[5]; 43 | assign next_crc_reg[10] = crc_reg[2] ^ crc_reg[24] ^ crc_reg[26] ^ 44 | crc_reg[27] ^ crc_reg[29] ^ crc_in[0] ^ crc_in[2] ^ crc_in[3] ^ crc_in[5]; 45 | assign next_crc_reg[11] = crc_reg[3] ^ crc_reg[24] ^ crc_reg[25] ^ 46 | crc_reg[27] ^ crc_reg[28] ^ crc_in[0] ^ crc_in[1] ^ crc_in[3] ^ crc_in[4]; 47 | assign next_crc_reg[12] = crc_reg[4] ^ crc_reg[24] ^ crc_reg[25] ^ 48 | crc_reg[26] ^ crc_reg[28] ^ crc_reg[29] ^ crc_reg[30] ^ crc_in[0] ^ 49 | crc_in[1] ^ crc_in[2] ^ crc_in[4] ^ crc_in[5] ^ crc_in[6]; 50 | assign next_crc_reg[13] = crc_reg[5] ^ crc_reg[25] ^ crc_reg[26] ^ 51 | crc_reg[27] ^ crc_reg[29] ^ crc_reg[30] ^ crc_reg[31] ^ crc_in[1] ^ 52 | crc_in[2] ^ crc_in[3] ^ crc_in[5] ^ crc_in[6] ^ crc_in[7]; 53 | assign next_crc_reg[14] = crc_reg[6] ^ crc_reg[26] ^ crc_reg[27] ^ 54 | crc_reg[28] ^ crc_reg[30] ^ crc_reg[31] ^ crc_in[2] ^ crc_in[3] ^ crc_in[4] 55 | ^ crc_in[6] ^ crc_in[7]; 56 | assign next_crc_reg[15] = crc_reg[7] ^ crc_reg[27] ^ crc_reg[28] ^ 57 | crc_reg[29] ^ crc_reg[31] ^ crc_in[3] ^ crc_in[4] ^ crc_in[5] ^ crc_in[7]; 58 | assign next_crc_reg[16] = crc_reg[8] ^ crc_reg[24] ^ crc_reg[28] ^ 59 | crc_reg[29] ^ crc_in[0] ^ crc_in[4] ^ crc_in[5]; 60 | assign next_crc_reg[17] = crc_reg[9] ^ crc_reg[25] ^ crc_reg[29] ^ 61 | crc_reg[30] ^ crc_in[1] ^ crc_in[5] ^ crc_in[6]; 62 | assign next_crc_reg[18] = crc_reg[10] ^ crc_reg[26] ^ crc_reg[30] ^ 63 | crc_reg[31] ^ crc_in[2] ^ crc_in[6] ^ crc_in[7]; 64 | assign next_crc_reg[19] = crc_reg[11] ^ crc_reg[27] ^ crc_reg[31] ^ 65 | crc_in[3] ^ crc_in[7]; 66 | assign next_crc_reg[20] = crc_reg[12] ^ crc_reg[28] ^ crc_in[4]; 67 | assign next_crc_reg[21] = crc_reg[13] ^ crc_reg[29] ^ crc_in[5]; 68 | assign next_crc_reg[22] = crc_reg[14] ^ crc_reg[24] ^ crc_in[0]; 69 | assign next_crc_reg[23] = crc_reg[15] ^ crc_reg[24] ^ crc_reg[25] ^ 70 | crc_reg[30] ^ crc_in[0] ^ crc_in[1] ^ crc_in[6]; 71 | assign next_crc_reg[24] = crc_reg[16] ^ crc_reg[25] ^ crc_reg[26] ^ 72 | crc_reg[31] ^ crc_in[1] ^ crc_in[2] ^ crc_in[7]; 73 | assign next_crc_reg[25] = crc_reg[17] ^ crc_reg[26] ^ crc_reg[27] ^ 74 | crc_in[2] ^ crc_in[3]; 75 | assign next_crc_reg[26] = crc_reg[18] ^ crc_reg[24] ^ crc_reg[27] ^ 76 | crc_reg[28] ^ crc_reg[30] ^ crc_in[0] ^ crc_in[3] ^ crc_in[4] ^ crc_in[6]; 77 | assign next_crc_reg[27] = crc_reg[19] ^ crc_reg[25] ^ crc_reg[28] ^ 78 | crc_reg[29] ^ crc_reg[31] ^ crc_in[1] ^ crc_in[4] ^ crc_in[5] ^ crc_in[7]; 79 | assign next_crc_reg[28] = crc_reg[20] ^ crc_reg[26] ^ crc_reg[29] ^ 80 | crc_reg[30] ^ crc_in[2] ^ crc_in[5] ^ crc_in[6]; 81 | assign next_crc_reg[29] = crc_reg[21] ^ crc_reg[27] ^ crc_reg[30] ^ 82 | crc_reg[31] ^ crc_in[3] ^ crc_in[6] ^ crc_in[7]; 83 | assign next_crc_reg[30] = crc_reg[22] ^ crc_reg[28] ^ crc_reg[31] ^ 84 | crc_in[4] ^ crc_in[7]; 85 | assign next_crc_reg[31] = crc_reg[23] ^ crc_reg[29] ^ crc_in[5]; 86 | // 87 | always@(posedge clk) 88 | begin 89 | case(state) // 90 | idle:begin // 91 | if(load) //l 92 | state <= compute; 93 | else 94 | state <= idle; 95 | end 96 | compute:begin 97 | if(d_finish) // 98 | state <= finish; 99 | else 100 | state <= compute; 101 | end 102 | finish:begin 103 | if(count==2) // 104 | state <= idle; 105 | else 106 | state <= finish; 107 | end 108 | endcase 109 | end 110 | always@(posedge clk or negedge rst) // 111 | if(rst) 112 | begin 113 | crc_reg[31:0] <= 32'b0000_0000_0000_0000_0000_0000_0000_0000; // 114 | 115 | state <= idle; 116 | count <= 2'b00; 117 | end 118 | else 119 | case(state) 120 | idle:begin // 121 | crc_reg[31:0] <= 122 | 32'b0000_0000_0000_0000_0000_0000_0000_0000; 123 | end 124 | compute:begin // 125 | crc_reg[31:0]<= next_crc_reg[31:0]; 126 | crc_out[7:0] <= crc_in[7:0]; 127 | end 128 | finish:begin // 129 | crc_reg[31:0] <= {crc_reg[23:0],8'b0000_0000}; 130 | crc_out[7:0] <= crc_reg[31:24]; 131 | end 132 | endcase 133 | endmodule 134 | -------------------------------------------------------------------------------- /CRC_32_paraller_test.v: -------------------------------------------------------------------------------- 1 | // 2 | module CRC_32_paraller_test; 3 | reg clk; 4 | reg rst; 5 | reg load; 6 | reg d_finish; 7 | reg [7:0] crc_in; 8 | wire [7:0] crc_out; 9 | parameter clk_period = 40; 10 | // 11 | initial 12 | begin 13 | #clk_period clk = 1; 14 | #clk_period rst = 1; 15 | #clk_period rst = 0; 16 | #clk_period crc_in[7:0] = 8'b1010_1010; // 17 | #clk_period load = 1; 18 | #clk_period load = 0; 19 | #clk_period d_finish = 0; 20 | #(10*clk_period) d_finish = 1; 21 | #clk_period d_finish = 0; 22 | end 23 | always #(clk_period/2) clk = ~clk; 24 | always #(clk_period) crc_in[7:0] = ~crc_in[7:0]; // 25 | // 26 | CRC_32_paraller 27 | u1(.clk(clk), .rst(rst), .load(load), .d_finish(d_finish), .crc_in(crc_in), .crc_out(crc_out)); 28 | endmodule 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | implement-CRC-32-in-Verilog 2 | =========================== 3 | Project in Course named 4 | DESIGN AND IMPLEMENTATION OF COMMUNICATION PROTOCOLS in FCU 5 | 6 | Include 7 | =========================== 8 | CRC-16-serial.v 9 | 10 | CRC-16-serial-test.v 11 | 12 | CRC-16-paraller.v 13 | 14 | CRC-16-paraller-test.v 15 | 16 | CRC-32-paraller.v 17 | 18 | CRC-32-paraller-test.v 19 | 20 | --------------------------------------------------------------------------------