From bf6287152e3f3daa425f1a28304b91fa1e805c8c Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Mon, 23 Oct 2023 01:53:59 -0700 Subject: [PATCH 01/29] Wrote initial module structure --- src/main/scala/d2dadapter/CRCGenerator.scala | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/main/scala/d2dadapter/CRCGenerator.scala diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala new file mode 100644 index 0000000..86dec0d --- /dev/null +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -0,0 +1,33 @@ +package edu.berkeley.cs.ucie.digital.d2dadapter + +import chisel3._ +import chisel3.util._ + +class CRCGenerator(width: Int) extends Module { + val io = IO(new Bundle { + val data_in = Input(UInt(width.W)) // Accepts next word of data from client + + val data_val = Input(Bool()) // Signal from client that data at data_in is valid and can be processed + // val clk = Input(Clock()) // synchronous clock signal + + val data_rdy = Output(Bool()) // Signal to client if generator is ready to accept another word of data + + val crc0_out = Output(UInt(8.W)) // CRC 0 Byte output + val crc1_out = Output(UInt(8.W)) // CRC 1 Byte output + val crc_val = Output(Bool()) // Signal to client that data on crc0_out and crc1_out are valid + }) + + // Output data registers + val CRC0 = RegInit(UInt(8.W), 0.U) + val CRC1 = RegInit(UInt(8.W), 0.U) + val CRC_Val = RegInit(Bool(), 1.U) + val Data_Rdy = RegInit(Bool(), 1.U) + + // CRC Calculating registers + val step = RegInit(UInt(log2Ceil(width).W), 0.U) + + + + +} + From 6a369443c3781c61109d4fc275ebfd1a35babb06 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Mon, 23 Oct 2023 02:06:54 -0700 Subject: [PATCH 02/29] Added Reset Logic --- src/main/scala/d2dadapter/CRCGenerator.scala | 25 ++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index 86dec0d..f125046 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -6,9 +6,11 @@ import chisel3.util._ class CRCGenerator(width: Int) extends Module { val io = IO(new Bundle { val data_in = Input(UInt(width.W)) // Accepts next word of data from client - val data_val = Input(Bool()) // Signal from client that data at data_in is valid and can be processed + // val clk = Input(Clock()) // synchronous clock signal + val rst = Input(Bool()) // reset CRC generator and registers + val data_rdy = Output(Bool()) // Signal to client if generator is ready to accept another word of data @@ -23,10 +25,29 @@ class CRCGenerator(width: Int) extends Module { val CRC_Val = RegInit(Bool(), 1.U) val Data_Rdy = RegInit(Bool(), 1.U) - // CRC Calculating registers + // CRC calculating registers val step = RegInit(UInt(log2Ceil(width).W), 0.U) + // Reset logic + when (io.rst) { + // Reset output data registers + CRC0 := 0.U + CRC1 := 0.U + CRC_Val := 1.U + Data_Rdy := 0.U + + // Propogate output data register + io.crc0_out := CRC0 + io.crc1_out := CRC1 + io.crc_val := CRC_Val + io.data_rdy := Data_Rdy + + // Reset CRC calculating registers + step := 0.U + } + + } From 472b6da82c6bfc50385d075776e90aaf1b1ffb70 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Mon, 23 Oct 2023 02:45:45 -0700 Subject: [PATCH 03/29] Generated CRC-16 Lookup table --- .../scala/d2dadapter/CRC16_8005_table.txt | 32 +++++++++++++++++++ .../d2dadapter/CRC16_8005_table_result.txt | 32 +++++++++++++++++++ src/main/scala/d2dadapter/generate_table.py | 28 ++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 src/main/scala/d2dadapter/CRC16_8005_table.txt create mode 100644 src/main/scala/d2dadapter/CRC16_8005_table_result.txt create mode 100644 src/main/scala/d2dadapter/generate_table.py diff --git a/src/main/scala/d2dadapter/CRC16_8005_table.txt b/src/main/scala/d2dadapter/CRC16_8005_table.txt new file mode 100644 index 0000000..3a386d6 --- /dev/null +++ b/src/main/scala/d2dadapter/CRC16_8005_table.txt @@ -0,0 +1,32 @@ +0x0000 0xc0c1 0xc181 0x0140 0xc301 0x03c0 0x0280 0xc241 +0xc601 0x06c0 0x0780 0xc741 0x0500 0xc5c1 0xc481 0x0440 +0xcc01 0x0cc0 0x0d80 0xcd41 0x0f00 0xcfc1 0xce81 0x0e40 +0x0a00 0xcac1 0xcb81 0x0b40 0xc901 0x09c0 0x0880 0xc841 +0xd801 0x18c0 0x1980 0xd941 0x1b00 0xdbc1 0xda81 0x1a40 +0x1e00 0xdec1 0xdf81 0x1f40 0xdd01 0x1dc0 0x1c80 0xdc41 +0x1400 0xd4c1 0xd581 0x1540 0xd701 0x17c0 0x1680 0xd641 +0xd201 0x12c0 0x1380 0xd341 0x1100 0xd1c1 0xd081 0x1040 +0xf001 0x30c0 0x3180 0xf141 0x3300 0xf3c1 0xf281 0x3240 +0x3600 0xf6c1 0xf781 0x3740 0xf501 0x35c0 0x3480 0xf441 +0x3c00 0xfcc1 0xfd81 0x3d40 0xff01 0x3fc0 0x3e80 0xfe41 +0xfa01 0x3ac0 0x3b80 0xfb41 0x3900 0xf9c1 0xf881 0x3840 +0x2800 0xe8c1 0xe981 0x2940 0xeb01 0x2bc0 0x2a80 0xea41 +0xee01 0x2ec0 0x2f80 0xef41 0x2d00 0xedc1 0xec81 0x2c40 +0xe401 0x24c0 0x2580 0xe541 0x2700 0xe7c1 0xe681 0x2640 +0x2200 0xe2c1 0xe381 0x2340 0xe101 0x21c0 0x2080 0xe041 +0xa001 0x60c0 0x6180 0xa141 0x6300 0xa3c1 0xa281 0x6240 +0x6600 0xa6c1 0xa781 0x6740 0xa501 0x65c0 0x6480 0xa441 +0x6c00 0xacc1 0xad81 0x6d40 0xaf01 0x6fc0 0x6e80 0xae41 +0xaa01 0x6ac0 0x6b80 0xab41 0x6900 0xa9c1 0xa881 0x6840 +0x7800 0xb8c1 0xb981 0x7940 0xbb01 0x7bc0 0x7a80 0xba41 +0xbe01 0x7ec0 0x7f80 0xbf41 0x7d00 0xbdc1 0xbc81 0x7c40 +0xb401 0x74c0 0x7580 0xb541 0x7700 0xb7c1 0xb681 0x7640 +0x7200 0xb2c1 0xb381 0x7340 0xb101 0x71c0 0x7080 0xb041 +0x5000 0x90c1 0x9181 0x5140 0x9301 0x53c0 0x5280 0x9241 +0x9601 0x56c0 0x5780 0x9741 0x5500 0x95c1 0x9481 0x5440 +0x9c01 0x5cc0 0x5d80 0x9d41 0x5f00 0x9fc1 0x9e81 0x5e40 +0x5a00 0x9ac1 0x9b81 0x5b40 0x9901 0x59c0 0x5880 0x9841 +0x8801 0x48c0 0x4980 0x8941 0x4b00 0x8bc1 0x8a81 0x4a40 +0x4e00 0x8ec1 0x8f81 0x4f40 0x8d01 0x4dc0 0x4c80 0x8c41 +0x4400 0x84c1 0x8581 0x4540 0x8701 0x47c0 0x4680 0x8641 +0x8201 0x42c0 0x4380 0x8341 0x4100 0x81c1 0x8081 0x4040 \ No newline at end of file diff --git a/src/main/scala/d2dadapter/CRC16_8005_table_result.txt b/src/main/scala/d2dadapter/CRC16_8005_table_result.txt new file mode 100644 index 0000000..a5fc7b3 --- /dev/null +++ b/src/main/scala/d2dadapter/CRC16_8005_table_result.txt @@ -0,0 +1,32 @@ +Array(0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, + 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, + 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, + 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, + 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, + 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, + 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, + 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, + 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, + 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, + 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, + 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, + 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, + 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, + 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, + 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, + 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, + 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, + 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, + 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, + 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, + 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, + 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, + 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, + 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, + 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, + 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, + 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, + 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, + 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, + 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, + 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040) diff --git a/src/main/scala/d2dadapter/generate_table.py b/src/main/scala/d2dadapter/generate_table.py new file mode 100644 index 0000000..2278979 --- /dev/null +++ b/src/main/scala/d2dadapter/generate_table.py @@ -0,0 +1,28 @@ + +table_name = "src\main\scala\d2dadapter\CRC16_8005_table.txt" + + +with open(table_name, "r") as table_file: + numbers = table_file.read().split() + +result = ['Array('] +line = 0 + +for i in range(len(numbers)): + if i > 0 and i % 8 == 0: + result.append(' ') + line += 1 + result[line] += f'{numbers[i]}, ' +result[line] = result[line][:-2] +result[line] += ')' + + +result_name = table_name.split('.txt')[0] + "_result.txt" +with open(result_name, "w") as result_file: + for line in result: + result_file.write(line + '\n') + + + + + From 78584bcfb601aeed36aa78d01e39a0a699af10f2 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Mon, 23 Oct 2023 02:49:18 -0700 Subject: [PATCH 04/29] Created lookup table class for CRC calculations --- .../scala/d2dadapter/CRC16Lookup8Bit.scala | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/main/scala/d2dadapter/CRC16Lookup8Bit.scala diff --git a/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala new file mode 100644 index 0000000..d1da232 --- /dev/null +++ b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala @@ -0,0 +1,44 @@ +package edu.berkeley.cs.ucie.digital.d2dadapter + +import chisel3._ +import chisel3.util._ + + +class CRC16Lookup { + + // Lookup table for CRC-16 (0x8005) polynomial + + val table = Array( 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, + 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, + 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, + 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, + 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, + 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, + 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, + 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, + 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, + 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, + 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, + 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, + 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, + 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, + 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, + 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, + 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, + 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, + 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, + 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, + 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, + 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, + 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, + 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, + 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, + 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, + 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, + 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, + 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, + 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, + 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, + 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040) + +} \ No newline at end of file From d27e94b1cdfc046ea19999634885874f61a0c99d Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Mon, 23 Oct 2023 14:18:43 -0700 Subject: [PATCH 05/29] Fixed lookup table format and successful import --- .../scala/d2dadapter/CRC16Lookup8Bit.scala | 64 +++++++++---------- .../d2dadapter/CRC16_8005_table_result.txt | 64 +++++++++---------- src/main/scala/d2dadapter/CRCGenerator.scala | 14 ++-- src/main/scala/d2dadapter/generate_table.py | 4 +- 4 files changed, 75 insertions(+), 71 deletions(-) diff --git a/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala index d1da232..97da1c6 100644 --- a/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala +++ b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala @@ -8,37 +8,37 @@ class CRC16Lookup { // Lookup table for CRC-16 (0x8005) polynomial - val table = Array( 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, - 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, - 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, - 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, - 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, - 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, - 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, - 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, - 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, - 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, - 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, - 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, - 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, - 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, - 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, - 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, - 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, - 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, - 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, - 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, - 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, - 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, - 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, - 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, - 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, - 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, - 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, - 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, - 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, - 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, - 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, - 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040) + val table = VecInit(0x0000.U, 0xc0c1.U, 0xc181.U, 0x0140.U, 0xc301.U, 0x03c0.U, 0x0280.U, 0xc241.U, + 0xc601.U, 0x06c0.U, 0x0780.U, 0xc741.U, 0x0500.U, 0xc5c1.U, 0xc481.U, 0x0440.U, + 0xcc01.U, 0x0cc0.U, 0x0d80.U, 0xcd41.U, 0x0f00.U, 0xcfc1.U, 0xce81.U, 0x0e40.U, + 0x0a00.U, 0xcac1.U, 0xcb81.U, 0x0b40.U, 0xc901.U, 0x09c0.U, 0x0880.U, 0xc841.U, + 0xd801.U, 0x18c0.U, 0x1980.U, 0xd941.U, 0x1b00.U, 0xdbc1.U, 0xda81.U, 0x1a40.U, + 0x1e00.U, 0xdec1.U, 0xdf81.U, 0x1f40.U, 0xdd01.U, 0x1dc0.U, 0x1c80.U, 0xdc41.U, + 0x1400.U, 0xd4c1.U, 0xd581.U, 0x1540.U, 0xd701.U, 0x17c0.U, 0x1680.U, 0xd641.U, + 0xd201.U, 0x12c0.U, 0x1380.U, 0xd341.U, 0x1100.U, 0xd1c1.U, 0xd081.U, 0x1040.U, + 0xf001.U, 0x30c0.U, 0x3180.U, 0xf141.U, 0x3300.U, 0xf3c1.U, 0xf281.U, 0x3240.U, + 0x3600.U, 0xf6c1.U, 0xf781.U, 0x3740.U, 0xf501.U, 0x35c0.U, 0x3480.U, 0xf441.U, + 0x3c00.U, 0xfcc1.U, 0xfd81.U, 0x3d40.U, 0xff01.U, 0x3fc0.U, 0x3e80.U, 0xfe41.U, + 0xfa01.U, 0x3ac0.U, 0x3b80.U, 0xfb41.U, 0x3900.U, 0xf9c1.U, 0xf881.U, 0x3840.U, + 0x2800.U, 0xe8c1.U, 0xe981.U, 0x2940.U, 0xeb01.U, 0x2bc0.U, 0x2a80.U, 0xea41.U, + 0xee01.U, 0x2ec0.U, 0x2f80.U, 0xef41.U, 0x2d00.U, 0xedc1.U, 0xec81.U, 0x2c40.U, + 0xe401.U, 0x24c0.U, 0x2580.U, 0xe541.U, 0x2700.U, 0xe7c1.U, 0xe681.U, 0x2640.U, + 0x2200.U, 0xe2c1.U, 0xe381.U, 0x2340.U, 0xe101.U, 0x21c0.U, 0x2080.U, 0xe041.U, + 0xa001.U, 0x60c0.U, 0x6180.U, 0xa141.U, 0x6300.U, 0xa3c1.U, 0xa281.U, 0x6240.U, + 0x6600.U, 0xa6c1.U, 0xa781.U, 0x6740.U, 0xa501.U, 0x65c0.U, 0x6480.U, 0xa441.U, + 0x6c00.U, 0xacc1.U, 0xad81.U, 0x6d40.U, 0xaf01.U, 0x6fc0.U, 0x6e80.U, 0xae41.U, + 0xaa01.U, 0x6ac0.U, 0x6b80.U, 0xab41.U, 0x6900.U, 0xa9c1.U, 0xa881.U, 0x6840.U, + 0x7800.U, 0xb8c1.U, 0xb981.U, 0x7940.U, 0xbb01.U, 0x7bc0.U, 0x7a80.U, 0xba41.U, + 0xbe01.U, 0x7ec0.U, 0x7f80.U, 0xbf41.U, 0x7d00.U, 0xbdc1.U, 0xbc81.U, 0x7c40.U, + 0xb401.U, 0x74c0.U, 0x7580.U, 0xb541.U, 0x7700.U, 0xb7c1.U, 0xb681.U, 0x7640.U, + 0x7200.U, 0xb2c1.U, 0xb381.U, 0x7340.U, 0xb101.U, 0x71c0.U, 0x7080.U, 0xb041.U, + 0x5000.U, 0x90c1.U, 0x9181.U, 0x5140.U, 0x9301.U, 0x53c0.U, 0x5280.U, 0x9241.U, + 0x9601.U, 0x56c0.U, 0x5780.U, 0x9741.U, 0x5500.U, 0x95c1.U, 0x9481.U, 0x5440.U, + 0x9c01.U, 0x5cc0.U, 0x5d80.U, 0x9d41.U, 0x5f00.U, 0x9fc1.U, 0x9e81.U, 0x5e40.U, + 0x5a00.U, 0x9ac1.U, 0x9b81.U, 0x5b40.U, 0x9901.U, 0x59c0.U, 0x5880.U, 0x9841.U, + 0x8801.U, 0x48c0.U, 0x4980.U, 0x8941.U, 0x4b00.U, 0x8bc1.U, 0x8a81.U, 0x4a40.U, + 0x4e00.U, 0x8ec1.U, 0x8f81.U, 0x4f40.U, 0x8d01.U, 0x4dc0.U, 0x4c80.U, 0x8c41.U, + 0x4400.U, 0x84c1.U, 0x8581.U, 0x4540.U, 0x8701.U, 0x47c0.U, 0x4680.U, 0x8641.U, + 0x8201.U, 0x42c0.U, 0x4380.U, 0x8341.U, 0x4100.U, 0x81c1.U, 0x8081.U, 0x4040.U) } \ No newline at end of file diff --git a/src/main/scala/d2dadapter/CRC16_8005_table_result.txt b/src/main/scala/d2dadapter/CRC16_8005_table_result.txt index a5fc7b3..a0fe4a2 100644 --- a/src/main/scala/d2dadapter/CRC16_8005_table_result.txt +++ b/src/main/scala/d2dadapter/CRC16_8005_table_result.txt @@ -1,32 +1,32 @@ -Array(0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, - 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, - 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, - 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, - 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, - 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, - 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, - 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, - 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, - 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, - 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, - 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, - 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, - 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, - 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, - 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, - 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, - 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, - 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, - 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, - 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, - 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, - 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, - 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, - 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, - 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, - 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, - 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, - 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, - 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, - 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, - 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040) +VecInit(0x0000.U, 0xc0c1.U, 0xc181.U, 0x0140.U, 0xc301.U, 0x03c0.U, 0x0280.U, 0xc241.U, + 0xc601.U, 0x06c0.U, 0x0780.U, 0xc741.U, 0x0500.U, 0xc5c1.U, 0xc481.U, 0x0440.U, + 0xcc01.U, 0x0cc0.U, 0x0d80.U, 0xcd41.U, 0x0f00.U, 0xcfc1.U, 0xce81.U, 0x0e40.U, + 0x0a00.U, 0xcac1.U, 0xcb81.U, 0x0b40.U, 0xc901.U, 0x09c0.U, 0x0880.U, 0xc841.U, + 0xd801.U, 0x18c0.U, 0x1980.U, 0xd941.U, 0x1b00.U, 0xdbc1.U, 0xda81.U, 0x1a40.U, + 0x1e00.U, 0xdec1.U, 0xdf81.U, 0x1f40.U, 0xdd01.U, 0x1dc0.U, 0x1c80.U, 0xdc41.U, + 0x1400.U, 0xd4c1.U, 0xd581.U, 0x1540.U, 0xd701.U, 0x17c0.U, 0x1680.U, 0xd641.U, + 0xd201.U, 0x12c0.U, 0x1380.U, 0xd341.U, 0x1100.U, 0xd1c1.U, 0xd081.U, 0x1040.U, + 0xf001.U, 0x30c0.U, 0x3180.U, 0xf141.U, 0x3300.U, 0xf3c1.U, 0xf281.U, 0x3240.U, + 0x3600.U, 0xf6c1.U, 0xf781.U, 0x3740.U, 0xf501.U, 0x35c0.U, 0x3480.U, 0xf441.U, + 0x3c00.U, 0xfcc1.U, 0xfd81.U, 0x3d40.U, 0xff01.U, 0x3fc0.U, 0x3e80.U, 0xfe41.U, + 0xfa01.U, 0x3ac0.U, 0x3b80.U, 0xfb41.U, 0x3900.U, 0xf9c1.U, 0xf881.U, 0x3840.U, + 0x2800.U, 0xe8c1.U, 0xe981.U, 0x2940.U, 0xeb01.U, 0x2bc0.U, 0x2a80.U, 0xea41.U, + 0xee01.U, 0x2ec0.U, 0x2f80.U, 0xef41.U, 0x2d00.U, 0xedc1.U, 0xec81.U, 0x2c40.U, + 0xe401.U, 0x24c0.U, 0x2580.U, 0xe541.U, 0x2700.U, 0xe7c1.U, 0xe681.U, 0x2640.U, + 0x2200.U, 0xe2c1.U, 0xe381.U, 0x2340.U, 0xe101.U, 0x21c0.U, 0x2080.U, 0xe041.U, + 0xa001.U, 0x60c0.U, 0x6180.U, 0xa141.U, 0x6300.U, 0xa3c1.U, 0xa281.U, 0x6240.U, + 0x6600.U, 0xa6c1.U, 0xa781.U, 0x6740.U, 0xa501.U, 0x65c0.U, 0x6480.U, 0xa441.U, + 0x6c00.U, 0xacc1.U, 0xad81.U, 0x6d40.U, 0xaf01.U, 0x6fc0.U, 0x6e80.U, 0xae41.U, + 0xaa01.U, 0x6ac0.U, 0x6b80.U, 0xab41.U, 0x6900.U, 0xa9c1.U, 0xa881.U, 0x6840.U, + 0x7800.U, 0xb8c1.U, 0xb981.U, 0x7940.U, 0xbb01.U, 0x7bc0.U, 0x7a80.U, 0xba41.U, + 0xbe01.U, 0x7ec0.U, 0x7f80.U, 0xbf41.U, 0x7d00.U, 0xbdc1.U, 0xbc81.U, 0x7c40.U, + 0xb401.U, 0x74c0.U, 0x7580.U, 0xb541.U, 0x7700.U, 0xb7c1.U, 0xb681.U, 0x7640.U, + 0x7200.U, 0xb2c1.U, 0xb381.U, 0x7340.U, 0xb101.U, 0x71c0.U, 0x7080.U, 0xb041.U, + 0x5000.U, 0x90c1.U, 0x9181.U, 0x5140.U, 0x9301.U, 0x53c0.U, 0x5280.U, 0x9241.U, + 0x9601.U, 0x56c0.U, 0x5780.U, 0x9741.U, 0x5500.U, 0x95c1.U, 0x9481.U, 0x5440.U, + 0x9c01.U, 0x5cc0.U, 0x5d80.U, 0x9d41.U, 0x5f00.U, 0x9fc1.U, 0x9e81.U, 0x5e40.U, + 0x5a00.U, 0x9ac1.U, 0x9b81.U, 0x5b40.U, 0x9901.U, 0x59c0.U, 0x5880.U, 0x9841.U, + 0x8801.U, 0x48c0.U, 0x4980.U, 0x8941.U, 0x4b00.U, 0x8bc1.U, 0x8a81.U, 0x4a40.U, + 0x4e00.U, 0x8ec1.U, 0x8f81.U, 0x4f40.U, 0x8d01.U, 0x4dc0.U, 0x4c80.U, 0x8c41.U, + 0x4400.U, 0x84c1.U, 0x8581.U, 0x4540.U, 0x8701.U, 0x47c0.U, 0x4680.U, 0x8641.U, + 0x8201.U, 0x42c0.U, 0x4380.U, 0x8341.U, 0x4100.U, 0x81c1.U, 0x8081.U, 0x4040.U) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index f125046..d1360de 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -2,6 +2,7 @@ package edu.berkeley.cs.ucie.digital.d2dadapter import chisel3._ import chisel3.util._ +import edu.berkeley.cs.ucie.digital.d2dadapter.CRC16Lookup class CRCGenerator(width: Int) extends Module { val io = IO(new Bundle { @@ -22,20 +23,23 @@ class CRCGenerator(width: Int) extends Module { // Output data registers val CRC0 = RegInit(UInt(8.W), 0.U) val CRC1 = RegInit(UInt(8.W), 0.U) - val CRC_Val = RegInit(Bool(), 1.U) - val Data_Rdy = RegInit(Bool(), 1.U) + val CRC_Val = RegInit(Bool(), true.B) + val Data_Rdy = RegInit(Bool(), true.B) // CRC calculating registers val step = RegInit(UInt(log2Ceil(width).W), 0.U) + val temp = RegInit(UInt(log2Ceil(width).W), 0.U) + // CRC calculating table + val table = new CRC16Lookup // Reset logic when (io.rst) { // Reset output data registers CRC0 := 0.U CRC1 := 0.U - CRC_Val := 1.U - Data_Rdy := 0.U + CRC_Val := true.B + Data_Rdy := true.B // Propogate output data register io.crc0_out := CRC0 @@ -47,7 +51,7 @@ class CRCGenerator(width: Int) extends Module { step := 0.U } - + // TODO: Sequential CRC Calculation } diff --git a/src/main/scala/d2dadapter/generate_table.py b/src/main/scala/d2dadapter/generate_table.py index 2278979..516b053 100644 --- a/src/main/scala/d2dadapter/generate_table.py +++ b/src/main/scala/d2dadapter/generate_table.py @@ -5,14 +5,14 @@ with open(table_name, "r") as table_file: numbers = table_file.read().split() -result = ['Array('] +result = ['VecInit('] line = 0 for i in range(len(numbers)): if i > 0 and i % 8 == 0: result.append(' ') line += 1 - result[line] += f'{numbers[i]}, ' + result[line] += f'{numbers[i]}.U, ' result[line] = result[line][:-2] result[line] += ')' From d2ab201499bf392488ec33a52d106dbc14dd811d Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Mon, 23 Oct 2023 19:21:08 -0700 Subject: [PATCH 06/29] Set up CRC Gen algorithm (not functional) --- src/main/scala/d2dadapter/CRCGenerator.scala | 42 +++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index d1360de..0e8d3da 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -4,7 +4,7 @@ import chisel3._ import chisel3.util._ import edu.berkeley.cs.ucie.digital.d2dadapter.CRC16Lookup -class CRCGenerator(width: Int) extends Module { +class CRCGenerator(width: Int) extends Module { // width is word size in bits (must be whole number of bytes) val io = IO(new Bundle { val data_in = Input(UInt(width.W)) // Accepts next word of data from client val data_val = Input(Bool()) // Signal from client that data at data_in is valid and can be processed @@ -23,29 +23,28 @@ class CRCGenerator(width: Int) extends Module { // Output data registers val CRC0 = RegInit(UInt(8.W), 0.U) val CRC1 = RegInit(UInt(8.W), 0.U) - val CRC_Val = RegInit(Bool(), true.B) - val Data_Rdy = RegInit(Bool(), true.B) // CRC calculating registers - val step = RegInit(UInt(log2Ceil(width).W), 0.U) - val temp = RegInit(UInt(log2Ceil(width).W), 0.U) + val step = RegInit(UInt(log2Ceil(width/8).W), 0.U) // Big enough to store byte position over width bits + val temp = RegInit(UInt(8.W), 0.U) // Stores 1 byte of data for lookup calculations + val Data_In = RegInit(UInt(width.W), 0.U) // Latches full word of data when data_rdy and data_val // CRC calculating table - val table = new CRC16Lookup + val lookup = new CRC16Lookup // Reset logic when (io.rst) { // Reset output data registers CRC0 := 0.U CRC1 := 0.U - CRC_Val := true.B - Data_Rdy := true.B // Propogate output data register io.crc0_out := CRC0 io.crc1_out := CRC1 - io.crc_val := CRC_Val - io.data_rdy := Data_Rdy + + // Signal Valid and Ready + io.crc_val := true.B + io.data_rdy := true.B // Reset CRC calculating registers step := 0.U @@ -53,6 +52,29 @@ class CRCGenerator(width: Int) extends Module { // TODO: Sequential CRC Calculation + // Latch data on data_rdy and data_val + when (io.data_val && io.data_rdy) { + step := (width/8).U - 1.U // Number of bytes in word + + Data_In := io.data_in + io.data_rdy := false.B + io.crc_val := false.B + } + + // Computation not finished when step is not 0 + when (step > 0.U) { + temp := CRC1 ^ Data_In(step*8.U - 1.U, step * 8.U) + CRC1 := CRC0 ^ lookup.table(temp)(15, 8) + CRC0 := lookup.table(temp)(8, 0) + step := step - 1.U + if (step == 0.U) { + io.crc0_out := CRC0 + io.crc1_out := CRC1 + io.crc_val := true.B + io.data_rdy := true.B + } + } + } From 7341b9f9f8951c6c3d046d6edf470a65e8518dba Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Wed, 25 Oct 2023 11:37:50 -0700 Subject: [PATCH 07/29] Updated CRCGenerator for Shift Register (non-functional) --- src/main/scala/d2dadapter/CRCGenerator.scala | 66 +++++++++++++------- src/test/scala/CRCGenerator.scala | 26 ++++++++ 2 files changed, 69 insertions(+), 23 deletions(-) create mode 100644 src/test/scala/CRCGenerator.scala diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index 0e8d3da..d6785c0 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -4,20 +4,25 @@ import chisel3._ import chisel3.util._ import edu.berkeley.cs.ucie.digital.d2dadapter.CRC16Lookup +// TODO: change variable names to snake_case + + + class CRCGenerator(width: Int) extends Module { // width is word size in bits (must be whole number of bytes) val io = IO(new Bundle { - val data_in = Input(UInt(width.W)) // Accepts next word of data from client - val data_val = Input(Bool()) // Signal from client that data at data_in is valid and can be processed + val data_in = Input(Bits(width.W)) // Accepts next word of data from consumer + val data_val = Input(Bool()) // Signal from consumer that data at data_in is valid and can be processed // val clk = Input(Clock()) // synchronous clock signal val rst = Input(Bool()) // reset CRC generator and registers + // TODO: Replace with ReadyValid3IO - val data_rdy = Output(Bool()) // Signal to client if generator is ready to accept another word of data + val data_rdy = Output(Bool()) // Signal to consumer if generator is ready to accept another word of data val crc0_out = Output(UInt(8.W)) // CRC 0 Byte output val crc1_out = Output(UInt(8.W)) // CRC 1 Byte output - val crc_val = Output(Bool()) // Signal to client that data on crc0_out and crc1_out are valid + val crc_val = Output(Bool()) // Signal to consumer that data on crc0_out and crc1_out are valid }) // Output data registers @@ -25,26 +30,39 @@ class CRCGenerator(width: Int) extends Module { // width is word size in bits (m val CRC1 = RegInit(UInt(8.W), 0.U) // CRC calculating registers - val step = RegInit(UInt(log2Ceil(width/8).W), 0.U) // Big enough to store byte position over width bits + val step = RegInit(UInt(log2Ceil(width/8).W), 0.U) // Big enough to store byte position over width bits val temp = RegInit(UInt(8.W), 0.U) // Stores 1 byte of data for lookup calculations - val Data_In = RegInit(UInt(width.W), 0.U) // Latches full word of data when data_rdy and data_val + // val Data_In = RegInit(Bits(width.W), 0.U) // Latches full word of data when data_rdy and data_val + + val Data_Rdy = RegInit(Bool(), false.B) + val CRC_Val = RegInit(Bool(), false.B) + + val shift_data = Wire(Bool()) + shift_data := false.B + val data_byte = ShiftRegister(io.data_in, 8, shift_data) + + // val data_byte_slice = Reg(Vec(width/8, Bits(8.W))) // Data work split into bytes // CRC calculating table val lookup = new CRC16Lookup + // Propogate output data register + io.crc0_out := CRC0 + io.crc1_out := CRC1 + + // Signal Valid and Ready + io.crc_val := CRC_Val + io.data_rdy := Data_Rdy + // Reset logic when (io.rst) { // Reset output data registers CRC0 := 0.U CRC1 := 0.U - // Propogate output data register - io.crc0_out := CRC0 - io.crc1_out := CRC1 - // Signal Valid and Ready - io.crc_val := true.B - io.data_rdy := true.B + CRC_Val := true.B + Data_Rdy := true.B // Reset CRC calculating registers step := 0.U @@ -53,25 +71,27 @@ class CRCGenerator(width: Int) extends Module { // width is word size in bits (m // TODO: Sequential CRC Calculation // Latch data on data_rdy and data_val - when (io.data_val && io.data_rdy) { - step := (width/8).U - 1.U // Number of bytes in word + - Data_In := io.data_in - io.data_rdy := false.B - io.crc_val := false.B + when (io.data_val & io.data_rdy) { + step := (width/8).U - 1.U // Number of bytes in word + data_byte := io.data_in + Data_Rdy := false.B + CRC_Val := false.B } // Computation not finished when step is not 0 when (step > 0.U) { - temp := CRC1 ^ Data_In(step*8.U - 1.U, step * 8.U) + + temp := CRC1 ^ data_byte(7, 0) // data_byte_slice(step) // Data_In(step*8.U - 1.U, step * 8.U) + shift_data := true.B + shift_data := false.B CRC1 := CRC0 ^ lookup.table(temp)(15, 8) - CRC0 := lookup.table(temp)(8, 0) + CRC0 := lookup.table(temp)(7, 0) step := step - 1.U if (step == 0.U) { - io.crc0_out := CRC0 - io.crc1_out := CRC1 - io.crc_val := true.B - io.data_rdy := true.B + CRC_Val := true.B + Data_Rdy := true.B } } diff --git a/src/test/scala/CRCGenerator.scala b/src/test/scala/CRCGenerator.scala new file mode 100644 index 0000000..ee9bae9 --- /dev/null +++ b/src/test/scala/CRCGenerator.scala @@ -0,0 +1,26 @@ +package edu.berkeley.cs.ucie.digital.d2dadapter + +import chisel3._ +import chiseltest._ +import org.scalatest.funspec.AnyFunSpec + +class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { + describe("CRCGenerator") { + it("Produce 16-bit CRC") { + test(new CRCGenerator(32)) { c => + //c.io.rst(true.B) + //c.clock.step() + //c.io.rst(false.B) + c.io.data_in.poke(0x26BC.U) + c.clock.step() + c.io.data_val.poke(true.B) + c.clock.step() + while (c.io.crc_val != true.B) { + c.clock.step() + } + c.io.crc0_out.expect(0x1B.U) + c.io.crc1_out.expect(0xD1.U) + } + } + } +} From 643b383f14f8f1a29a2a18173a9e47d7280cb757 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Wed, 25 Oct 2023 18:53:36 -0700 Subject: [PATCH 08/29] Compiled, functioning shift, algorithm incorrect --- src/main/scala/d2dadapter/CRCGenerator.scala | 34 +++++++------------ .../scala/{ => d2dadapter}/CRCGenerator.scala | 18 ++++++---- 2 files changed, 24 insertions(+), 28 deletions(-) rename src/test/scala/{ => d2dadapter}/CRCGenerator.scala (57%) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index d6785c0..47e0a69 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -29,19 +29,16 @@ class CRCGenerator(width: Int) extends Module { // width is word size in bits (m val CRC0 = RegInit(UInt(8.W), 0.U) val CRC1 = RegInit(UInt(8.W), 0.U) - // CRC calculating registers - val step = RegInit(UInt(log2Ceil(width/8).W), 0.U) // Big enough to store byte position over width bits - val temp = RegInit(UInt(8.W), 0.U) // Stores 1 byte of data for lookup calculations - // val Data_In = RegInit(Bits(width.W), 0.U) // Latches full word of data when data_rdy and data_val - + // Ouput signal resgisters val Data_Rdy = RegInit(Bool(), false.B) val CRC_Val = RegInit(Bool(), false.B) - val shift_data = Wire(Bool()) - shift_data := false.B - val data_byte = ShiftRegister(io.data_in, 8, shift_data) + + // CRC calculating registers + val step = RegInit(UInt(log2Ceil(width/8+1).W), 0.U) // Big enough to store byte position over width bits + val temp = RegInit(UInt(8.W), 0.U) // Stores 1 byte of data for lookup calculations + val Data_In = RegInit(Bits(width.W), 0.U) // Latches full word of data when data_rdy and data_val - // val data_byte_slice = Reg(Vec(width/8, Bits(8.W))) // Data work split into bytes // CRC calculating table val lookup = new CRC16Lookup @@ -71,28 +68,23 @@ class CRCGenerator(width: Int) extends Module { // width is word size in bits (m // TODO: Sequential CRC Calculation // Latch data on data_rdy and data_val - - when (io.data_val & io.data_rdy) { - step := (width/8).U - 1.U // Number of bytes in word - data_byte := io.data_in + step := (width/8).U // Number of bytes in word + Data_In := io.data_in Data_Rdy := false.B CRC_Val := false.B } // Computation not finished when step is not 0 when (step > 0.U) { - - temp := CRC1 ^ data_byte(7, 0) // data_byte_slice(step) // Data_In(step*8.U - 1.U, step * 8.U) - shift_data := true.B - shift_data := false.B + temp := CRC1 ^ Data_In(7, 0) CRC1 := CRC0 ^ lookup.table(temp)(15, 8) CRC0 := lookup.table(temp)(7, 0) + Data_In := Data_In >> 8 step := step - 1.U - if (step == 0.U) { - CRC_Val := true.B - Data_Rdy := true.B - } + } .otherwise { + CRC_Val := true.B + Data_Rdy := true.B } diff --git a/src/test/scala/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala similarity index 57% rename from src/test/scala/CRCGenerator.scala rename to src/test/scala/d2dadapter/CRCGenerator.scala index ee9bae9..d847892 100644 --- a/src/test/scala/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -3,23 +3,27 @@ package edu.berkeley.cs.ucie.digital.d2dadapter import chisel3._ import chiseltest._ import org.scalatest.funspec.AnyFunSpec +import chiseltest.simulator.WriteVcdAnnotation + + + class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { describe("CRCGenerator") { it("Produce 16-bit CRC") { - test(new CRCGenerator(32)) { c => - //c.io.rst(true.B) - //c.clock.step() - //c.io.rst(false.B) - c.io.data_in.poke(0x26BC.U) + test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => + c.io.rst.poke(true.B) + c.clock.step() + c.io.rst.poke(false.B) + c.io.data_in.poke(0x7E348ADB) c.clock.step() c.io.data_val.poke(true.B) c.clock.step() while (c.io.crc_val != true.B) { c.clock.step() } - c.io.crc0_out.expect(0x1B.U) - c.io.crc1_out.expect(0xD1.U) + c.io.crc1_out.expect(0xDD.U) + c.io.crc0_out.expect(0x53.U) } } } From 2b9bb8abc6782af6de032da75e926c75bf4bd195 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Thu, 26 Oct 2023 03:30:32 -0700 Subject: [PATCH 09/29] Test Structure fixed --- src/main/scala/d2dadapter/CRCGenerator.scala | 12 ++++++------ src/test/scala/d2dadapter/CRCGenerator.scala | 10 ++++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index 47e0a69..9812c15 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -36,7 +36,6 @@ class CRCGenerator(width: Int) extends Module { // width is word size in bits (m // CRC calculating registers val step = RegInit(UInt(log2Ceil(width/8+1).W), 0.U) // Big enough to store byte position over width bits - val temp = RegInit(UInt(8.W), 0.U) // Stores 1 byte of data for lookup calculations val Data_In = RegInit(Bits(width.W), 0.U) // Latches full word of data when data_rdy and data_val @@ -71,17 +70,18 @@ class CRCGenerator(width: Int) extends Module { // width is word size in bits (m when (io.data_val & io.data_rdy) { step := (width/8).U // Number of bytes in word Data_In := io.data_in - Data_Rdy := false.B CRC_Val := false.B + Data_Rdy := false.B } // Computation not finished when step is not 0 when (step > 0.U) { - temp := CRC1 ^ Data_In(7, 0) - CRC1 := CRC0 ^ lookup.table(temp)(15, 8) - CRC0 := lookup.table(temp)(7, 0) - Data_In := Data_In >> 8 + CRC1 := CRC0 ^ lookup.table(CRC1 ^ Data_In(width-1, width-8))(15, 8) + CRC0 := lookup.table(CRC1 ^ Data_In(width-1, width-8))(7, 0) + Data_In := Data_In << 8 step := step - 1.U + CRC_Val := false.B + Data_Rdy := false.B } .otherwise { CRC_Val := true.B Data_Rdy := true.B diff --git a/src/test/scala/d2dadapter/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala index d847892..6c07703 100644 --- a/src/test/scala/d2dadapter/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -15,15 +15,17 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { c.io.rst.poke(true.B) c.clock.step() c.io.rst.poke(false.B) - c.io.data_in.poke(0x7E348ADB) + c.io.data_in.poke("hF3D1AB23".U) c.clock.step() c.io.data_val.poke(true.B) c.clock.step() - while (c.io.crc_val != true.B) { + c.io.data_val.poke(false.B) + c.clock.step() + while (c.io.crc_val.peek().litValue != 1) { c.clock.step() } - c.io.crc1_out.expect(0xDD.U) - c.io.crc0_out.expect(0x53.U) + c.io.crc1_out.expect("hC4".U) + c.io.crc0_out.expect("h14".U) } } } From a0ed00193083b02b3cb38499d94f06416d64c3e3 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Thu, 26 Oct 2023 12:31:46 -0700 Subject: [PATCH 10/29] Resolved issues, added test cases --- .../scala/d2dadapter/CRC16Lookup8Bit.scala | 67 ++++++++++--------- .../scala/d2dadapter/CRC16_8005_table.txt | 48 +++++-------- .../d2dadapter/CRC16_8005_table_result.txt | 64 +++++++++--------- src/main/scala/d2dadapter/CRCGenerator.scala | 3 + 4 files changed, 86 insertions(+), 96 deletions(-) diff --git a/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala index 97da1c6..2e68266 100644 --- a/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala +++ b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala @@ -8,37 +8,40 @@ class CRC16Lookup { // Lookup table for CRC-16 (0x8005) polynomial - val table = VecInit(0x0000.U, 0xc0c1.U, 0xc181.U, 0x0140.U, 0xc301.U, 0x03c0.U, 0x0280.U, 0xc241.U, - 0xc601.U, 0x06c0.U, 0x0780.U, 0xc741.U, 0x0500.U, 0xc5c1.U, 0xc481.U, 0x0440.U, - 0xcc01.U, 0x0cc0.U, 0x0d80.U, 0xcd41.U, 0x0f00.U, 0xcfc1.U, 0xce81.U, 0x0e40.U, - 0x0a00.U, 0xcac1.U, 0xcb81.U, 0x0b40.U, 0xc901.U, 0x09c0.U, 0x0880.U, 0xc841.U, - 0xd801.U, 0x18c0.U, 0x1980.U, 0xd941.U, 0x1b00.U, 0xdbc1.U, 0xda81.U, 0x1a40.U, - 0x1e00.U, 0xdec1.U, 0xdf81.U, 0x1f40.U, 0xdd01.U, 0x1dc0.U, 0x1c80.U, 0xdc41.U, - 0x1400.U, 0xd4c1.U, 0xd581.U, 0x1540.U, 0xd701.U, 0x17c0.U, 0x1680.U, 0xd641.U, - 0xd201.U, 0x12c0.U, 0x1380.U, 0xd341.U, 0x1100.U, 0xd1c1.U, 0xd081.U, 0x1040.U, - 0xf001.U, 0x30c0.U, 0x3180.U, 0xf141.U, 0x3300.U, 0xf3c1.U, 0xf281.U, 0x3240.U, - 0x3600.U, 0xf6c1.U, 0xf781.U, 0x3740.U, 0xf501.U, 0x35c0.U, 0x3480.U, 0xf441.U, - 0x3c00.U, 0xfcc1.U, 0xfd81.U, 0x3d40.U, 0xff01.U, 0x3fc0.U, 0x3e80.U, 0xfe41.U, - 0xfa01.U, 0x3ac0.U, 0x3b80.U, 0xfb41.U, 0x3900.U, 0xf9c1.U, 0xf881.U, 0x3840.U, - 0x2800.U, 0xe8c1.U, 0xe981.U, 0x2940.U, 0xeb01.U, 0x2bc0.U, 0x2a80.U, 0xea41.U, - 0xee01.U, 0x2ec0.U, 0x2f80.U, 0xef41.U, 0x2d00.U, 0xedc1.U, 0xec81.U, 0x2c40.U, - 0xe401.U, 0x24c0.U, 0x2580.U, 0xe541.U, 0x2700.U, 0xe7c1.U, 0xe681.U, 0x2640.U, - 0x2200.U, 0xe2c1.U, 0xe381.U, 0x2340.U, 0xe101.U, 0x21c0.U, 0x2080.U, 0xe041.U, - 0xa001.U, 0x60c0.U, 0x6180.U, 0xa141.U, 0x6300.U, 0xa3c1.U, 0xa281.U, 0x6240.U, - 0x6600.U, 0xa6c1.U, 0xa781.U, 0x6740.U, 0xa501.U, 0x65c0.U, 0x6480.U, 0xa441.U, - 0x6c00.U, 0xacc1.U, 0xad81.U, 0x6d40.U, 0xaf01.U, 0x6fc0.U, 0x6e80.U, 0xae41.U, - 0xaa01.U, 0x6ac0.U, 0x6b80.U, 0xab41.U, 0x6900.U, 0xa9c1.U, 0xa881.U, 0x6840.U, - 0x7800.U, 0xb8c1.U, 0xb981.U, 0x7940.U, 0xbb01.U, 0x7bc0.U, 0x7a80.U, 0xba41.U, - 0xbe01.U, 0x7ec0.U, 0x7f80.U, 0xbf41.U, 0x7d00.U, 0xbdc1.U, 0xbc81.U, 0x7c40.U, - 0xb401.U, 0x74c0.U, 0x7580.U, 0xb541.U, 0x7700.U, 0xb7c1.U, 0xb681.U, 0x7640.U, - 0x7200.U, 0xb2c1.U, 0xb381.U, 0x7340.U, 0xb101.U, 0x71c0.U, 0x7080.U, 0xb041.U, - 0x5000.U, 0x90c1.U, 0x9181.U, 0x5140.U, 0x9301.U, 0x53c0.U, 0x5280.U, 0x9241.U, - 0x9601.U, 0x56c0.U, 0x5780.U, 0x9741.U, 0x5500.U, 0x95c1.U, 0x9481.U, 0x5440.U, - 0x9c01.U, 0x5cc0.U, 0x5d80.U, 0x9d41.U, 0x5f00.U, 0x9fc1.U, 0x9e81.U, 0x5e40.U, - 0x5a00.U, 0x9ac1.U, 0x9b81.U, 0x5b40.U, 0x9901.U, 0x59c0.U, 0x5880.U, 0x9841.U, - 0x8801.U, 0x48c0.U, 0x4980.U, 0x8941.U, 0x4b00.U, 0x8bc1.U, 0x8a81.U, 0x4a40.U, - 0x4e00.U, 0x8ec1.U, 0x8f81.U, 0x4f40.U, 0x8d01.U, 0x4dc0.U, 0x4c80.U, 0x8c41.U, - 0x4400.U, 0x84c1.U, 0x8581.U, 0x4540.U, 0x8701.U, 0x47c0.U, 0x4680.U, 0x8641.U, - 0x8201.U, 0x42c0.U, 0x4380.U, 0x8341.U, 0x4100.U, 0x81c1.U, 0x8081.U, 0x4040.U) + val table = VecInit(0x0000.U, 0x8005.U, 0x800F.U, 0x000A.U, 0x801B.U, 0x001E.U, 0x0014.U, 0x8011.U, + 0x8033.U, 0x0036.U, 0x003C.U, 0x8039.U, 0x0028.U, 0x802D.U, 0x8027.U, 0x0022.U, + 0x8063.U, 0x0066.U, 0x006C.U, 0x8069.U, 0x0078.U, 0x807D.U, 0x8077.U, 0x0072.U, + 0x0050.U, 0x8055.U, 0x805F.U, 0x005A.U, 0x804B.U, 0x004E.U, 0x0044.U, 0x8041.U, + 0x80C3.U, 0x00C6.U, 0x00CC.U, 0x80C9.U, 0x00D8.U, 0x80DD.U, 0x80D7.U, 0x00D2.U, + 0x00F0.U, 0x80F5.U, 0x80FF.U, 0x00FA.U, 0x80EB.U, 0x00EE.U, 0x00E4.U, 0x80E1.U, + 0x00A0.U, 0x80A5.U, 0x80AF.U, 0x00AA.U, 0x80BB.U, 0x00BE.U, 0x00B4.U, 0x80B1.U, + 0x8093.U, 0x0096.U, 0x009C.U, 0x8099.U, 0x0088.U, 0x808D.U, 0x8087.U, 0x0082.U, + 0x8183.U, 0x0186.U, 0x018C.U, 0x8189.U, 0x0198.U, 0x819D.U, 0x8197.U, 0x0192.U, + 0x01B0.U, 0x81B5.U, 0x81BF.U, 0x01BA.U, 0x81AB.U, 0x01AE.U, 0x01A4.U, 0x81A1.U, + 0x01E0.U, 0x81E5.U, 0x81EF.U, 0x01EA.U, 0x81FB.U, 0x01FE.U, 0x01F4.U, 0x81F1.U, + 0x81D3.U, 0x01D6.U, 0x01DC.U, 0x81D9.U, 0x01C8.U, 0x81CD.U, 0x81C7.U, 0x01C2.U, + 0x0140.U, 0x8145.U, 0x814F.U, 0x014A.U, 0x815B.U, 0x015E.U, 0x0154.U, 0x8151.U, + 0x8173.U, 0x0176.U, 0x017C.U, 0x8179.U, 0x0168.U, 0x816D.U, 0x8167.U, 0x0162.U, + 0x8123.U, 0x0126.U, 0x012C.U, 0x8129.U, 0x0138.U, 0x813D.U, 0x8137.U, 0x0132.U, + 0x0110.U, 0x8115.U, 0x811F.U, 0x011A.U, 0x810B.U, 0x010E.U, 0x0104.U, 0x8101.U, + 0x8303.U, 0x0306.U, 0x030C.U, 0x8309.U, 0x0318.U, 0x831D.U, 0x8317.U, 0x0312.U, + 0x0330.U, 0x8335.U, 0x833F.U, 0x033A.U, 0x832B.U, 0x032E.U, 0x0324.U, 0x8321.U, + 0x0360.U, 0x8365.U, 0x836F.U, 0x036A.U, 0x837B.U, 0x037E.U, 0x0374.U, 0x8371.U, + 0x8353.U, 0x0356.U, 0x035C.U, 0x8359.U, 0x0348.U, 0x834D.U, 0x8347.U, 0x0342.U, + 0x03C0.U, 0x83C5.U, 0x83CF.U, 0x03CA.U, 0x83DB.U, 0x03DE.U, 0x03D4.U, 0x83D1.U, + 0x83F3.U, 0x03F6.U, 0x03FC.U, 0x83F9.U, 0x03E8.U, 0x83ED.U, 0x83E7.U, 0x03E2.U, + 0x83A3.U, 0x03A6.U, 0x03AC.U, 0x83A9.U, 0x03B8.U, 0x83BD.U, 0x83B7.U, 0x03B2.U, + 0x0390.U, 0x8395.U, 0x839F.U, 0x039A.U, 0x838B.U, 0x038E.U, 0x0384.U, 0x8381.U, + 0x0280.U, 0x8285.U, 0x828F.U, 0x028A.U, 0x829B.U, 0x029E.U, 0x0294.U, 0x8291.U, + 0x82B3.U, 0x02B6.U, 0x02BC.U, 0x82B9.U, 0x02A8.U, 0x82AD.U, 0x82A7.U, 0x02A2.U, + 0x82E3.U, 0x02E6.U, 0x02EC.U, 0x82E9.U, 0x02F8.U, 0x82FD.U, 0x82F7.U, 0x02F2.U, + 0x02D0.U, 0x82D5.U, 0x82DF.U, 0x02DA.U, 0x82CB.U, 0x02CE.U, 0x02C4.U, 0x82C1.U, + 0x8243.U, 0x0246.U, 0x024C.U, 0x8249.U, 0x0258.U, 0x825D.U, 0x8257.U, 0x0252.U, + 0x0270.U, 0x8275.U, 0x827F.U, 0x027A.U, 0x826B.U, 0x026E.U, 0x0264.U, 0x8261.U, + 0x0220.U, 0x8225.U, 0x822F.U, 0x022A.U, 0x823B.U, 0x023E.U, 0x0234.U, 0x8231.U, + 0x8213.U, 0x0216.U, 0x021C.U, 0x8219.U, 0x0208.U, 0x820D.U, 0x8207.U, 0x0202.U) + + + } \ No newline at end of file diff --git a/src/main/scala/d2dadapter/CRC16_8005_table.txt b/src/main/scala/d2dadapter/CRC16_8005_table.txt index 3a386d6..bc291df 100644 --- a/src/main/scala/d2dadapter/CRC16_8005_table.txt +++ b/src/main/scala/d2dadapter/CRC16_8005_table.txt @@ -1,32 +1,16 @@ -0x0000 0xc0c1 0xc181 0x0140 0xc301 0x03c0 0x0280 0xc241 -0xc601 0x06c0 0x0780 0xc741 0x0500 0xc5c1 0xc481 0x0440 -0xcc01 0x0cc0 0x0d80 0xcd41 0x0f00 0xcfc1 0xce81 0x0e40 -0x0a00 0xcac1 0xcb81 0x0b40 0xc901 0x09c0 0x0880 0xc841 -0xd801 0x18c0 0x1980 0xd941 0x1b00 0xdbc1 0xda81 0x1a40 -0x1e00 0xdec1 0xdf81 0x1f40 0xdd01 0x1dc0 0x1c80 0xdc41 -0x1400 0xd4c1 0xd581 0x1540 0xd701 0x17c0 0x1680 0xd641 -0xd201 0x12c0 0x1380 0xd341 0x1100 0xd1c1 0xd081 0x1040 -0xf001 0x30c0 0x3180 0xf141 0x3300 0xf3c1 0xf281 0x3240 -0x3600 0xf6c1 0xf781 0x3740 0xf501 0x35c0 0x3480 0xf441 -0x3c00 0xfcc1 0xfd81 0x3d40 0xff01 0x3fc0 0x3e80 0xfe41 -0xfa01 0x3ac0 0x3b80 0xfb41 0x3900 0xf9c1 0xf881 0x3840 -0x2800 0xe8c1 0xe981 0x2940 0xeb01 0x2bc0 0x2a80 0xea41 -0xee01 0x2ec0 0x2f80 0xef41 0x2d00 0xedc1 0xec81 0x2c40 -0xe401 0x24c0 0x2580 0xe541 0x2700 0xe7c1 0xe681 0x2640 -0x2200 0xe2c1 0xe381 0x2340 0xe101 0x21c0 0x2080 0xe041 -0xa001 0x60c0 0x6180 0xa141 0x6300 0xa3c1 0xa281 0x6240 -0x6600 0xa6c1 0xa781 0x6740 0xa501 0x65c0 0x6480 0xa441 -0x6c00 0xacc1 0xad81 0x6d40 0xaf01 0x6fc0 0x6e80 0xae41 -0xaa01 0x6ac0 0x6b80 0xab41 0x6900 0xa9c1 0xa881 0x6840 -0x7800 0xb8c1 0xb981 0x7940 0xbb01 0x7bc0 0x7a80 0xba41 -0xbe01 0x7ec0 0x7f80 0xbf41 0x7d00 0xbdc1 0xbc81 0x7c40 -0xb401 0x74c0 0x7580 0xb541 0x7700 0xb7c1 0xb681 0x7640 -0x7200 0xb2c1 0xb381 0x7340 0xb101 0x71c0 0x7080 0xb041 -0x5000 0x90c1 0x9181 0x5140 0x9301 0x53c0 0x5280 0x9241 -0x9601 0x56c0 0x5780 0x9741 0x5500 0x95c1 0x9481 0x5440 -0x9c01 0x5cc0 0x5d80 0x9d41 0x5f00 0x9fc1 0x9e81 0x5e40 -0x5a00 0x9ac1 0x9b81 0x5b40 0x9901 0x59c0 0x5880 0x9841 -0x8801 0x48c0 0x4980 0x8941 0x4b00 0x8bc1 0x8a81 0x4a40 -0x4e00 0x8ec1 0x8f81 0x4f40 0x8d01 0x4dc0 0x4c80 0x8c41 -0x4400 0x84c1 0x8581 0x4540 0x8701 0x47c0 0x4680 0x8641 -0x8201 0x42c0 0x4380 0x8341 0x4100 0x81c1 0x8081 0x4040 \ No newline at end of file +0x0000 0x8005 0x800F 0x000A 0x801B 0x001E 0x0014 0x8011 0x8033 0x0036 0x003C 0x8039 0x0028 0x802D 0x8027 0x0022 +0x8063 0x0066 0x006C 0x8069 0x0078 0x807D 0x8077 0x0072 0x0050 0x8055 0x805F 0x005A 0x804B 0x004E 0x0044 0x8041 +0x80C3 0x00C6 0x00CC 0x80C9 0x00D8 0x80DD 0x80D7 0x00D2 0x00F0 0x80F5 0x80FF 0x00FA 0x80EB 0x00EE 0x00E4 0x80E1 +0x00A0 0x80A5 0x80AF 0x00AA 0x80BB 0x00BE 0x00B4 0x80B1 0x8093 0x0096 0x009C 0x8099 0x0088 0x808D 0x8087 0x0082 +0x8183 0x0186 0x018C 0x8189 0x0198 0x819D 0x8197 0x0192 0x01B0 0x81B5 0x81BF 0x01BA 0x81AB 0x01AE 0x01A4 0x81A1 +0x01E0 0x81E5 0x81EF 0x01EA 0x81FB 0x01FE 0x01F4 0x81F1 0x81D3 0x01D6 0x01DC 0x81D9 0x01C8 0x81CD 0x81C7 0x01C2 +0x0140 0x8145 0x814F 0x014A 0x815B 0x015E 0x0154 0x8151 0x8173 0x0176 0x017C 0x8179 0x0168 0x816D 0x8167 0x0162 +0x8123 0x0126 0x012C 0x8129 0x0138 0x813D 0x8137 0x0132 0x0110 0x8115 0x811F 0x011A 0x810B 0x010E 0x0104 0x8101 +0x8303 0x0306 0x030C 0x8309 0x0318 0x831D 0x8317 0x0312 0x0330 0x8335 0x833F 0x033A 0x832B 0x032E 0x0324 0x8321 +0x0360 0x8365 0x836F 0x036A 0x837B 0x037E 0x0374 0x8371 0x8353 0x0356 0x035C 0x8359 0x0348 0x834D 0x8347 0x0342 +0x03C0 0x83C5 0x83CF 0x03CA 0x83DB 0x03DE 0x03D4 0x83D1 0x83F3 0x03F6 0x03FC 0x83F9 0x03E8 0x83ED 0x83E7 0x03E2 +0x83A3 0x03A6 0x03AC 0x83A9 0x03B8 0x83BD 0x83B7 0x03B2 0x0390 0x8395 0x839F 0x039A 0x838B 0x038E 0x0384 0x8381 +0x0280 0x8285 0x828F 0x028A 0x829B 0x029E 0x0294 0x8291 0x82B3 0x02B6 0x02BC 0x82B9 0x02A8 0x82AD 0x82A7 0x02A2 +0x82E3 0x02E6 0x02EC 0x82E9 0x02F8 0x82FD 0x82F7 0x02F2 0x02D0 0x82D5 0x82DF 0x02DA 0x82CB 0x02CE 0x02C4 0x82C1 +0x8243 0x0246 0x024C 0x8249 0x0258 0x825D 0x8257 0x0252 0x0270 0x8275 0x827F 0x027A 0x826B 0x026E 0x0264 0x8261 +0x0220 0x8225 0x822F 0x022A 0x823B 0x023E 0x0234 0x8231 0x8213 0x0216 0x021C 0x8219 0x0208 0x820D 0x8207 0x0202 \ No newline at end of file diff --git a/src/main/scala/d2dadapter/CRC16_8005_table_result.txt b/src/main/scala/d2dadapter/CRC16_8005_table_result.txt index a0fe4a2..d3a2efe 100644 --- a/src/main/scala/d2dadapter/CRC16_8005_table_result.txt +++ b/src/main/scala/d2dadapter/CRC16_8005_table_result.txt @@ -1,32 +1,32 @@ -VecInit(0x0000.U, 0xc0c1.U, 0xc181.U, 0x0140.U, 0xc301.U, 0x03c0.U, 0x0280.U, 0xc241.U, - 0xc601.U, 0x06c0.U, 0x0780.U, 0xc741.U, 0x0500.U, 0xc5c1.U, 0xc481.U, 0x0440.U, - 0xcc01.U, 0x0cc0.U, 0x0d80.U, 0xcd41.U, 0x0f00.U, 0xcfc1.U, 0xce81.U, 0x0e40.U, - 0x0a00.U, 0xcac1.U, 0xcb81.U, 0x0b40.U, 0xc901.U, 0x09c0.U, 0x0880.U, 0xc841.U, - 0xd801.U, 0x18c0.U, 0x1980.U, 0xd941.U, 0x1b00.U, 0xdbc1.U, 0xda81.U, 0x1a40.U, - 0x1e00.U, 0xdec1.U, 0xdf81.U, 0x1f40.U, 0xdd01.U, 0x1dc0.U, 0x1c80.U, 0xdc41.U, - 0x1400.U, 0xd4c1.U, 0xd581.U, 0x1540.U, 0xd701.U, 0x17c0.U, 0x1680.U, 0xd641.U, - 0xd201.U, 0x12c0.U, 0x1380.U, 0xd341.U, 0x1100.U, 0xd1c1.U, 0xd081.U, 0x1040.U, - 0xf001.U, 0x30c0.U, 0x3180.U, 0xf141.U, 0x3300.U, 0xf3c1.U, 0xf281.U, 0x3240.U, - 0x3600.U, 0xf6c1.U, 0xf781.U, 0x3740.U, 0xf501.U, 0x35c0.U, 0x3480.U, 0xf441.U, - 0x3c00.U, 0xfcc1.U, 0xfd81.U, 0x3d40.U, 0xff01.U, 0x3fc0.U, 0x3e80.U, 0xfe41.U, - 0xfa01.U, 0x3ac0.U, 0x3b80.U, 0xfb41.U, 0x3900.U, 0xf9c1.U, 0xf881.U, 0x3840.U, - 0x2800.U, 0xe8c1.U, 0xe981.U, 0x2940.U, 0xeb01.U, 0x2bc0.U, 0x2a80.U, 0xea41.U, - 0xee01.U, 0x2ec0.U, 0x2f80.U, 0xef41.U, 0x2d00.U, 0xedc1.U, 0xec81.U, 0x2c40.U, - 0xe401.U, 0x24c0.U, 0x2580.U, 0xe541.U, 0x2700.U, 0xe7c1.U, 0xe681.U, 0x2640.U, - 0x2200.U, 0xe2c1.U, 0xe381.U, 0x2340.U, 0xe101.U, 0x21c0.U, 0x2080.U, 0xe041.U, - 0xa001.U, 0x60c0.U, 0x6180.U, 0xa141.U, 0x6300.U, 0xa3c1.U, 0xa281.U, 0x6240.U, - 0x6600.U, 0xa6c1.U, 0xa781.U, 0x6740.U, 0xa501.U, 0x65c0.U, 0x6480.U, 0xa441.U, - 0x6c00.U, 0xacc1.U, 0xad81.U, 0x6d40.U, 0xaf01.U, 0x6fc0.U, 0x6e80.U, 0xae41.U, - 0xaa01.U, 0x6ac0.U, 0x6b80.U, 0xab41.U, 0x6900.U, 0xa9c1.U, 0xa881.U, 0x6840.U, - 0x7800.U, 0xb8c1.U, 0xb981.U, 0x7940.U, 0xbb01.U, 0x7bc0.U, 0x7a80.U, 0xba41.U, - 0xbe01.U, 0x7ec0.U, 0x7f80.U, 0xbf41.U, 0x7d00.U, 0xbdc1.U, 0xbc81.U, 0x7c40.U, - 0xb401.U, 0x74c0.U, 0x7580.U, 0xb541.U, 0x7700.U, 0xb7c1.U, 0xb681.U, 0x7640.U, - 0x7200.U, 0xb2c1.U, 0xb381.U, 0x7340.U, 0xb101.U, 0x71c0.U, 0x7080.U, 0xb041.U, - 0x5000.U, 0x90c1.U, 0x9181.U, 0x5140.U, 0x9301.U, 0x53c0.U, 0x5280.U, 0x9241.U, - 0x9601.U, 0x56c0.U, 0x5780.U, 0x9741.U, 0x5500.U, 0x95c1.U, 0x9481.U, 0x5440.U, - 0x9c01.U, 0x5cc0.U, 0x5d80.U, 0x9d41.U, 0x5f00.U, 0x9fc1.U, 0x9e81.U, 0x5e40.U, - 0x5a00.U, 0x9ac1.U, 0x9b81.U, 0x5b40.U, 0x9901.U, 0x59c0.U, 0x5880.U, 0x9841.U, - 0x8801.U, 0x48c0.U, 0x4980.U, 0x8941.U, 0x4b00.U, 0x8bc1.U, 0x8a81.U, 0x4a40.U, - 0x4e00.U, 0x8ec1.U, 0x8f81.U, 0x4f40.U, 0x8d01.U, 0x4dc0.U, 0x4c80.U, 0x8c41.U, - 0x4400.U, 0x84c1.U, 0x8581.U, 0x4540.U, 0x8701.U, 0x47c0.U, 0x4680.U, 0x8641.U, - 0x8201.U, 0x42c0.U, 0x4380.U, 0x8341.U, 0x4100.U, 0x81c1.U, 0x8081.U, 0x4040.U) +VecInit(0x0000.U, 0x8005.U, 0x800F.U, 0x000A.U, 0x801B.U, 0x001E.U, 0x0014.U, 0x8011.U, + 0x8033.U, 0x0036.U, 0x003C.U, 0x8039.U, 0x0028.U, 0x802D.U, 0x8027.U, 0x0022.U, + 0x8063.U, 0x0066.U, 0x006C.U, 0x8069.U, 0x0078.U, 0x807D.U, 0x8077.U, 0x0072.U, + 0x0050.U, 0x8055.U, 0x805F.U, 0x005A.U, 0x804B.U, 0x004E.U, 0x0044.U, 0x8041.U, + 0x80C3.U, 0x00C6.U, 0x00CC.U, 0x80C9.U, 0x00D8.U, 0x80DD.U, 0x80D7.U, 0x00D2.U, + 0x00F0.U, 0x80F5.U, 0x80FF.U, 0x00FA.U, 0x80EB.U, 0x00EE.U, 0x00E4.U, 0x80E1.U, + 0x00A0.U, 0x80A5.U, 0x80AF.U, 0x00AA.U, 0x80BB.U, 0x00BE.U, 0x00B4.U, 0x80B1.U, + 0x8093.U, 0x0096.U, 0x009C.U, 0x8099.U, 0x0088.U, 0x808D.U, 0x8087.U, 0x0082.U, + 0x8183.U, 0x0186.U, 0x018C.U, 0x8189.U, 0x0198.U, 0x819D.U, 0x8197.U, 0x0192.U, + 0x01B0.U, 0x81B5.U, 0x81BF.U, 0x01BA.U, 0x81AB.U, 0x01AE.U, 0x01A4.U, 0x81A1.U, + 0x01E0.U, 0x81E5.U, 0x81EF.U, 0x01EA.U, 0x81FB.U, 0x01FE.U, 0x01F4.U, 0x81F1.U, + 0x81D3.U, 0x01D6.U, 0x01DC.U, 0x81D9.U, 0x01C8.U, 0x81CD.U, 0x81C7.U, 0x01C2.U, + 0x0140.U, 0x8145.U, 0x814F.U, 0x014A.U, 0x815B.U, 0x015E.U, 0x0154.U, 0x8151.U, + 0x8173.U, 0x0176.U, 0x017C.U, 0x8179.U, 0x0168.U, 0x816D.U, 0x8167.U, 0x0162.U, + 0x8123.U, 0x0126.U, 0x012C.U, 0x8129.U, 0x0138.U, 0x813D.U, 0x8137.U, 0x0132.U, + 0x0110.U, 0x8115.U, 0x811F.U, 0x011A.U, 0x810B.U, 0x010E.U, 0x0104.U, 0x8101.U, + 0x8303.U, 0x0306.U, 0x030C.U, 0x8309.U, 0x0318.U, 0x831D.U, 0x8317.U, 0x0312.U, + 0x0330.U, 0x8335.U, 0x833F.U, 0x033A.U, 0x832B.U, 0x032E.U, 0x0324.U, 0x8321.U, + 0x0360.U, 0x8365.U, 0x836F.U, 0x036A.U, 0x837B.U, 0x037E.U, 0x0374.U, 0x8371.U, + 0x8353.U, 0x0356.U, 0x035C.U, 0x8359.U, 0x0348.U, 0x834D.U, 0x8347.U, 0x0342.U, + 0x03C0.U, 0x83C5.U, 0x83CF.U, 0x03CA.U, 0x83DB.U, 0x03DE.U, 0x03D4.U, 0x83D1.U, + 0x83F3.U, 0x03F6.U, 0x03FC.U, 0x83F9.U, 0x03E8.U, 0x83ED.U, 0x83E7.U, 0x03E2.U, + 0x83A3.U, 0x03A6.U, 0x03AC.U, 0x83A9.U, 0x03B8.U, 0x83BD.U, 0x83B7.U, 0x03B2.U, + 0x0390.U, 0x8395.U, 0x839F.U, 0x039A.U, 0x838B.U, 0x038E.U, 0x0384.U, 0x8381.U, + 0x0280.U, 0x8285.U, 0x828F.U, 0x028A.U, 0x829B.U, 0x029E.U, 0x0294.U, 0x8291.U, + 0x82B3.U, 0x02B6.U, 0x02BC.U, 0x82B9.U, 0x02A8.U, 0x82AD.U, 0x82A7.U, 0x02A2.U, + 0x82E3.U, 0x02E6.U, 0x02EC.U, 0x82E9.U, 0x02F8.U, 0x82FD.U, 0x82F7.U, 0x02F2.U, + 0x02D0.U, 0x82D5.U, 0x82DF.U, 0x02DA.U, 0x82CB.U, 0x02CE.U, 0x02C4.U, 0x82C1.U, + 0x8243.U, 0x0246.U, 0x024C.U, 0x8249.U, 0x0258.U, 0x825D.U, 0x8257.U, 0x0252.U, + 0x0270.U, 0x8275.U, 0x827F.U, 0x027A.U, 0x826B.U, 0x026E.U, 0x0264.U, 0x8261.U, + 0x0220.U, 0x8225.U, 0x822F.U, 0x022A.U, 0x823B.U, 0x023E.U, 0x0234.U, 0x8231.U, + 0x8213.U, 0x0216.U, 0x021C.U, 0x8219.U, 0x0208.U, 0x820D.U, 0x8207.U, 0x0202.U) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index 9812c15..aeb4dac 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -7,6 +7,9 @@ import edu.berkeley.cs.ucie.digital.d2dadapter.CRC16Lookup // TODO: change variable names to snake_case +/** Generates the CRC of data using the polynomial x^16 + x^15 + x^2 + 1 + * + */ class CRCGenerator(width: Int) extends Module { // width is word size in bits (must be whole number of bytes) val io = IO(new Bundle { From ad22060b07340663ab525ae0bd3634d1af981871 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Thu, 26 Oct 2023 12:32:21 -0700 Subject: [PATCH 11/29] Added test cases --- src/test/scala/d2dadapter/CRCGenerator.scala | 82 ++++++++++++++++++-- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/src/test/scala/d2dadapter/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala index 6c07703..866f2e5 100644 --- a/src/test/scala/d2dadapter/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -5,12 +5,49 @@ import chiseltest._ import org.scalatest.funspec.AnyFunSpec import chiseltest.simulator.WriteVcdAnnotation +class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { + describe("CRCGenerator") { + it("should produce h8BC as the 16-bit CRC of hF3D1AB23") { + test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => + c.io.rst.poke(true.B) + c.clock.step() + c.io.rst.poke(false.B) + c.io.data_in.poke("hF3D1AB23".U) + c.clock.step() + c.io.data_val.poke(true.B) + c.clock.step() + c.io.data_val.poke(false.B) + c.clock.step() + while (c.io.crc_val.peek().litValue != 1) { + c.clock.step() + } + c.io.crc1_out.expect("h08".U) + c.io.crc0_out.expect("hBC".U) + } + } + it("should produce hD34D as the 16-bit CRC of hB481A391") { + test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => + c.io.rst.poke(true.B) + c.clock.step() + c.io.rst.poke(false.B) + c.io.data_in.poke("hB481A391".U) + c.clock.step() + c.io.data_val.poke(true.B) + c.clock.step() + c.io.data_val.poke(false.B) + c.clock.step() + while (c.io.crc_val.peek().litValue != 1) { + c.clock.step() + } + c.io.crc1_out.expect("hD3".U) + c.io.crc0_out.expect("h4D".U) -class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { - describe("CRCGenerator") { - it("Produce 16-bit CRC") { + } + } + + it("should produce back to back valid 16-bit CRCs of hF3D1AB23 and hB481A391") { test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => c.io.rst.poke(true.B) c.clock.step() @@ -24,8 +61,43 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { while (c.io.crc_val.peek().litValue != 1) { c.clock.step() } - c.io.crc1_out.expect("hC4".U) - c.io.crc0_out.expect("h14".U) + c.io.crc1_out.expect("h08".U) + c.io.crc0_out.expect("hBC".U) + + c.io.rst.poke(true.B) + c.clock.step() + c.io.rst.poke(false.B) + c.io.data_in.poke("hB481A391".U) + c.clock.step() + c.io.data_val.poke(true.B) + c.clock.step() + c.io.data_val.poke(false.B) + c.clock.step() + while (c.io.crc_val.peek().litValue != 1) { + c.clock.step() + } + c.io.crc1_out.expect("hD3".U) + c.io.crc0_out.expect("h4D".U) + } + } + + it("should produce h5557 as the 16-bit CRC of he3c3598edd...") { + test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { c => + c.io.rst.poke(true.B) + c.clock.step() + c.io.rst.poke(false.B) + val num = "he3c3598e_dd1a3be2_d429ad05_2b927c61_c2ba41b6_fc7ac0df_093b5d8b_b754d97d_36b105a3_64fce07b_bc68ccef_3b391448_225bc955_7052a494_49168926_c2429be9_66775914_9bf34300_ceee9ae0_7b681d27_bba8b55f_0eadc080_b0955182_0d8200ce_31a58b25_6c8086f6_d535913e_e7867535_f5e15126_f682f852_0fb831c3_ba7e5b69" + c.io.data_in.poke((num).U) + c.clock.step() + c.io.data_val.poke(true.B) + c.clock.step() + c.io.data_val.poke(false.B) + c.clock.step() + while (c.io.crc_val.peek().litValue != 1) { + c.clock.step() + } + c.io.crc1_out.expect("h55".U) + c.io.crc0_out.expect("h57".U) } } } From eaead7ed0a36604fcf7f0a9e1acebaf5542057c6 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Thu, 26 Oct 2023 12:55:13 -0700 Subject: [PATCH 12/29] style: Refactored to snake_case, split test modules --- src/main/scala/d2dadapter/CRCGenerator.scala | 68 +++++++++----------- src/test/scala/d2dadapter/CRCGenerator.scala | 4 +- 2 files changed, 33 insertions(+), 39 deletions(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index aeb4dac..bc9dd72 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -13,15 +13,13 @@ import edu.berkeley.cs.ucie.digital.d2dadapter.CRC16Lookup class CRCGenerator(width: Int) extends Module { // width is word size in bits (must be whole number of bytes) val io = IO(new Bundle { - val data_in = Input(Bits(width.W)) // Accepts next word of data from consumer - val data_val = Input(Bool()) // Signal from consumer that data at data_in is valid and can be processed - - // val clk = Input(Clock()) // synchronous clock signal val rst = Input(Bool()) // reset CRC generator and registers - // TODO: Replace with ReadyValid3IO - + // TODO: Replace with ReadyValid3IO + val data_in = Input(Bits(width.W)) // Accepts next word of data from consumer + val data_val = Input(Bool()) // Signal from consumer that data at data_in is valid and can be processed val data_rdy = Output(Bool()) // Signal to consumer if generator is ready to accept another word of data + // TODO: Replace with ReadyValid3IO val crc0_out = Output(UInt(8.W)) // CRC 0 Byte output val crc1_out = Output(UInt(8.W)) // CRC 1 Byte output @@ -29,67 +27,61 @@ class CRCGenerator(width: Int) extends Module { // width is word size in bits (m }) // Output data registers - val CRC0 = RegInit(UInt(8.W), 0.U) - val CRC1 = RegInit(UInt(8.W), 0.U) - - // Ouput signal resgisters - val Data_Rdy = RegInit(Bool(), false.B) - val CRC_Val = RegInit(Bool(), false.B) + val crc0 = RegInit(UInt(8.W), 0.U) + val crc1 = RegInit(UInt(8.W), 0.U) + // Output signal registers + val data_rdy = RegInit(Bool(), false.B) + val crc_val = RegInit(Bool(), false.B) // CRC calculating registers - val step = RegInit(UInt(log2Ceil(width/8+1).W), 0.U) // Big enough to store byte position over width bits - val Data_In = RegInit(Bits(width.W), 0.U) // Latches full word of data when data_rdy and data_val - + val step = RegInit(UInt(log2Ceil(width/8+1).W), 0.U) // Store number of bytes in width bits + val data_in = RegInit(Bits(width.W), 0.U) // Latches full word of data when data_rdy and data_val // CRC calculating table val lookup = new CRC16Lookup // Propogate output data register - io.crc0_out := CRC0 - io.crc1_out := CRC1 + io.crc0_out := crc0 + io.crc1_out := crc1 // Signal Valid and Ready - io.crc_val := CRC_Val - io.data_rdy := Data_Rdy + io.crc_val := crc_val + io.data_rdy := data_rdy // Reset logic when (io.rst) { // Reset output data registers - CRC0 := 0.U - CRC1 := 0.U + crc0 := 0.U + crc1 := 0.U // Signal Valid and Ready - CRC_Val := true.B - Data_Rdy := true.B + crc_val := true.B + data_rdy := true.B // Reset CRC calculating registers step := 0.U } - // TODO: Sequential CRC Calculation - // Latch data on data_rdy and data_val when (io.data_val & io.data_rdy) { - step := (width/8).U // Number of bytes in word - Data_In := io.data_in - CRC_Val := false.B - Data_Rdy := false.B + step := (width/8).U // Number of bytes in word + data_in := io.data_in + crc_val := false.B + data_rdy := false.B } // Computation not finished when step is not 0 when (step > 0.U) { - CRC1 := CRC0 ^ lookup.table(CRC1 ^ Data_In(width-1, width-8))(15, 8) - CRC0 := lookup.table(CRC1 ^ Data_In(width-1, width-8))(7, 0) - Data_In := Data_In << 8 + crc1 := crc0 ^ lookup.table(crc1 ^ data_in(width-1, width-8))(15, 8) + crc0 := lookup.table(crc1 ^ data_in(width-1, width-8))(7, 0) + data_in := data_in << 8 step := step - 1.U - CRC_Val := false.B - Data_Rdy := false.B + crc_val := false.B + data_rdy := false.B } .otherwise { - CRC_Val := true.B - Data_Rdy := true.B + crc_val := true.B + data_rdy := true.B } - - } diff --git a/src/test/scala/d2dadapter/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala index 866f2e5..6b504a4 100644 --- a/src/test/scala/d2dadapter/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -6,7 +6,7 @@ import org.scalatest.funspec.AnyFunSpec import chiseltest.simulator.WriteVcdAnnotation class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { - describe("CRCGenerator") { + describe("CRCGenerator, 32-bit messages") { it("should produce h8BC as the 16-bit CRC of hF3D1AB23") { test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => c.io.rst.poke(true.B) @@ -80,7 +80,9 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { c.io.crc0_out.expect("h4D".U) } } + } + describe("CRCGenerator, 1024-bit messages") { it("should produce h5557 as the 16-bit CRC of he3c3598edd...") { test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { c => c.io.rst.poke(true.B) From ba286e38b5da30853f3718dd9acf0f670bf5e4d1 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Thu, 26 Oct 2023 13:25:15 -0700 Subject: [PATCH 13/29] Refactored data_in to message Decoupled ReadyValid3IO --- src/main/scala/d2dadapter/CRCGenerator.scala | 35 ++++++------- src/test/scala/d2dadapter/CRCGenerator.scala | 52 ++++++++++++++------ 2 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index bc9dd72..ce44c44 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -2,6 +2,7 @@ package edu.berkeley.cs.ucie.digital.d2dadapter import chisel3._ import chisel3.util._ +import chisel3.util.Decoupled import edu.berkeley.cs.ucie.digital.d2dadapter.CRC16Lookup // TODO: change variable names to snake_case @@ -13,13 +14,9 @@ import edu.berkeley.cs.ucie.digital.d2dadapter.CRC16Lookup class CRCGenerator(width: Int) extends Module { // width is word size in bits (must be whole number of bytes) val io = IO(new Bundle { - val rst = Input(Bool()) // reset CRC generator and registers + val rst = Input(Bool()) - // TODO: Replace with ReadyValid3IO - val data_in = Input(Bits(width.W)) // Accepts next word of data from consumer - val data_val = Input(Bool()) // Signal from consumer that data at data_in is valid and can be processed - val data_rdy = Output(Bool()) // Signal to consumer if generator is ready to accept another word of data - // TODO: Replace with ReadyValid3IO + val message = Flipped(Decoupled(Bits(width.W))) val crc0_out = Output(UInt(8.W)) // CRC 0 Byte output val crc1_out = Output(UInt(8.W)) // CRC 1 Byte output @@ -31,12 +28,12 @@ class CRCGenerator(width: Int) extends Module { // width is word size in bits (m val crc1 = RegInit(UInt(8.W), 0.U) // Output signal registers - val data_rdy = RegInit(Bool(), false.B) + val message_ready = RegInit(Bool(), false.B) val crc_val = RegInit(Bool(), false.B) // CRC calculating registers val step = RegInit(UInt(log2Ceil(width/8+1).W), 0.U) // Store number of bytes in width bits - val data_in = RegInit(Bits(width.W), 0.U) // Latches full word of data when data_rdy and data_val + val message_bits = RegInit(Bits(width.W), 0.U) // Latches full word of data when message_ready and data_val // CRC calculating table val lookup = new CRC16Lookup @@ -47,7 +44,7 @@ class CRCGenerator(width: Int) extends Module { // width is word size in bits (m // Signal Valid and Ready io.crc_val := crc_val - io.data_rdy := data_rdy + io.message.ready := message_ready // Reset logic when (io.rst) { @@ -57,31 +54,31 @@ class CRCGenerator(width: Int) extends Module { // width is word size in bits (m // Signal Valid and Ready crc_val := true.B - data_rdy := true.B + message_ready := true.B // Reset CRC calculating registers step := 0.U } - // Latch data on data_rdy and data_val - when (io.data_val & io.data_rdy) { + // Latch data on message_ready and data_val + when (io.message.valid & io.message.ready) { step := (width/8).U // Number of bytes in word - data_in := io.data_in + message_bits := io.message.bits crc_val := false.B - data_rdy := false.B + message_ready := false.B } // Computation not finished when step is not 0 when (step > 0.U) { - crc1 := crc0 ^ lookup.table(crc1 ^ data_in(width-1, width-8))(15, 8) - crc0 := lookup.table(crc1 ^ data_in(width-1, width-8))(7, 0) - data_in := data_in << 8 + crc1 := crc0 ^ lookup.table(crc1 ^ message_bits(width-1, width-8))(15, 8) + crc0 := lookup.table(crc1 ^ message_bits(width-1, width-8))(7, 0) + message_bits := message_bits << 8 step := step - 1.U crc_val := false.B - data_rdy := false.B + message_ready := false.B } .otherwise { crc_val := true.B - data_rdy := true.B + message_ready := true.B } } diff --git a/src/test/scala/d2dadapter/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala index 6b504a4..a17691c 100644 --- a/src/test/scala/d2dadapter/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -12,11 +12,11 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { c.io.rst.poke(true.B) c.clock.step() c.io.rst.poke(false.B) - c.io.data_in.poke("hF3D1AB23".U) + c.io.message.bits.poke("hF3D1AB23".U) c.clock.step() - c.io.data_val.poke(true.B) + c.io.message.valid.poke(true.B) c.clock.step() - c.io.data_val.poke(false.B) + c.io.message.valid.poke(false.B) c.clock.step() while (c.io.crc_val.peek().litValue != 1) { c.clock.step() @@ -31,11 +31,11 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { c.io.rst.poke(true.B) c.clock.step() c.io.rst.poke(false.B) - c.io.data_in.poke("hB481A391".U) + c.io.message.bits.poke("hB481A391".U) c.clock.step() - c.io.data_val.poke(true.B) + c.io.message.valid.poke(true.B) c.clock.step() - c.io.data_val.poke(false.B) + c.io.message.valid.poke(false.B) c.clock.step() while (c.io.crc_val.peek().litValue != 1) { c.clock.step() @@ -52,11 +52,11 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { c.io.rst.poke(true.B) c.clock.step() c.io.rst.poke(false.B) - c.io.data_in.poke("hF3D1AB23".U) + c.io.message.bits.poke("hF3D1AB23".U) c.clock.step() - c.io.data_val.poke(true.B) + c.io.message.valid.poke(true.B) c.clock.step() - c.io.data_val.poke(false.B) + c.io.message.valid.poke(false.B) c.clock.step() while (c.io.crc_val.peek().litValue != 1) { c.clock.step() @@ -67,11 +67,11 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { c.io.rst.poke(true.B) c.clock.step() c.io.rst.poke(false.B) - c.io.data_in.poke("hB481A391".U) + c.io.message.bits.poke("hB481A391".U) c.clock.step() - c.io.data_val.poke(true.B) + c.io.message.valid.poke(true.B) c.clock.step() - c.io.data_val.poke(false.B) + c.io.message.valid.poke(false.B) c.clock.step() while (c.io.crc_val.peek().litValue != 1) { c.clock.step() @@ -83,17 +83,17 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { } describe("CRCGenerator, 1024-bit messages") { - it("should produce h5557 as the 16-bit CRC of he3c3598edd...") { + it("should produce h5557 as the 16-bit CRC of he3c3598e...") { test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { c => c.io.rst.poke(true.B) c.clock.step() c.io.rst.poke(false.B) val num = "he3c3598e_dd1a3be2_d429ad05_2b927c61_c2ba41b6_fc7ac0df_093b5d8b_b754d97d_36b105a3_64fce07b_bc68ccef_3b391448_225bc955_7052a494_49168926_c2429be9_66775914_9bf34300_ceee9ae0_7b681d27_bba8b55f_0eadc080_b0955182_0d8200ce_31a58b25_6c8086f6_d535913e_e7867535_f5e15126_f682f852_0fb831c3_ba7e5b69" - c.io.data_in.poke((num).U) + c.io.message.bits.poke((num).U) c.clock.step() - c.io.data_val.poke(true.B) + c.io.message.valid.poke(true.B) c.clock.step() - c.io.data_val.poke(false.B) + c.io.message.valid.poke(false.B) c.clock.step() while (c.io.crc_val.peek().litValue != 1) { c.clock.step() @@ -102,5 +102,25 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { c.io.crc0_out.expect("h57".U) } } + + it("should produce h5b39 as the 16-bit CRC of h21940141...") { + test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { c => + c.io.rst.poke(true.B) + c.clock.step() + c.io.rst.poke(false.B) + val num = "h21940141_94204c5b_66aadb33_39ff52dd_59187e4d_8d7f45a0_92f32508_9fdc1174_62f98566_b5767b24_38ffcf48_dcd48173_0d2d0706_19653a06_a208e4d2_ed55d4a7_6cf0e086_db7be8f6_95d30337_c72e6072_1651c46c_3f9a38dd_50d0b5a9_4a8f23e3_f1915b39_e0570141_22bdfa54_293ad6fe_3ef3d240_ae894873_835dc657_881e5c7d" + c.io.message.bits.poke((num).U) + c.clock.step() + c.io.message.valid.poke(true.B) + c.clock.step() + c.io.message.valid.poke(false.B) + c.clock.step() + while (c.io.crc_val.peek().litValue != 1) { + c.clock.step() + } + c.io.crc1_out.expect("h5b".U) + c.io.crc0_out.expect("h39".U) + } + } } } From 6ee2f2bb5e734d7248539f9759051454fa676867 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Thu, 26 Oct 2023 13:37:05 -0700 Subject: [PATCH 14/29] Remove helper files --- .../scala/d2dadapter/CRC16_8005_table.txt | 16 ---------- .../d2dadapter/CRC16_8005_table_result.txt | 32 ------------------- src/main/scala/d2dadapter/generate_table.py | 28 ---------------- 3 files changed, 76 deletions(-) delete mode 100644 src/main/scala/d2dadapter/CRC16_8005_table.txt delete mode 100644 src/main/scala/d2dadapter/CRC16_8005_table_result.txt delete mode 100644 src/main/scala/d2dadapter/generate_table.py diff --git a/src/main/scala/d2dadapter/CRC16_8005_table.txt b/src/main/scala/d2dadapter/CRC16_8005_table.txt deleted file mode 100644 index bc291df..0000000 --- a/src/main/scala/d2dadapter/CRC16_8005_table.txt +++ /dev/null @@ -1,16 +0,0 @@ -0x0000 0x8005 0x800F 0x000A 0x801B 0x001E 0x0014 0x8011 0x8033 0x0036 0x003C 0x8039 0x0028 0x802D 0x8027 0x0022 -0x8063 0x0066 0x006C 0x8069 0x0078 0x807D 0x8077 0x0072 0x0050 0x8055 0x805F 0x005A 0x804B 0x004E 0x0044 0x8041 -0x80C3 0x00C6 0x00CC 0x80C9 0x00D8 0x80DD 0x80D7 0x00D2 0x00F0 0x80F5 0x80FF 0x00FA 0x80EB 0x00EE 0x00E4 0x80E1 -0x00A0 0x80A5 0x80AF 0x00AA 0x80BB 0x00BE 0x00B4 0x80B1 0x8093 0x0096 0x009C 0x8099 0x0088 0x808D 0x8087 0x0082 -0x8183 0x0186 0x018C 0x8189 0x0198 0x819D 0x8197 0x0192 0x01B0 0x81B5 0x81BF 0x01BA 0x81AB 0x01AE 0x01A4 0x81A1 -0x01E0 0x81E5 0x81EF 0x01EA 0x81FB 0x01FE 0x01F4 0x81F1 0x81D3 0x01D6 0x01DC 0x81D9 0x01C8 0x81CD 0x81C7 0x01C2 -0x0140 0x8145 0x814F 0x014A 0x815B 0x015E 0x0154 0x8151 0x8173 0x0176 0x017C 0x8179 0x0168 0x816D 0x8167 0x0162 -0x8123 0x0126 0x012C 0x8129 0x0138 0x813D 0x8137 0x0132 0x0110 0x8115 0x811F 0x011A 0x810B 0x010E 0x0104 0x8101 -0x8303 0x0306 0x030C 0x8309 0x0318 0x831D 0x8317 0x0312 0x0330 0x8335 0x833F 0x033A 0x832B 0x032E 0x0324 0x8321 -0x0360 0x8365 0x836F 0x036A 0x837B 0x037E 0x0374 0x8371 0x8353 0x0356 0x035C 0x8359 0x0348 0x834D 0x8347 0x0342 -0x03C0 0x83C5 0x83CF 0x03CA 0x83DB 0x03DE 0x03D4 0x83D1 0x83F3 0x03F6 0x03FC 0x83F9 0x03E8 0x83ED 0x83E7 0x03E2 -0x83A3 0x03A6 0x03AC 0x83A9 0x03B8 0x83BD 0x83B7 0x03B2 0x0390 0x8395 0x839F 0x039A 0x838B 0x038E 0x0384 0x8381 -0x0280 0x8285 0x828F 0x028A 0x829B 0x029E 0x0294 0x8291 0x82B3 0x02B6 0x02BC 0x82B9 0x02A8 0x82AD 0x82A7 0x02A2 -0x82E3 0x02E6 0x02EC 0x82E9 0x02F8 0x82FD 0x82F7 0x02F2 0x02D0 0x82D5 0x82DF 0x02DA 0x82CB 0x02CE 0x02C4 0x82C1 -0x8243 0x0246 0x024C 0x8249 0x0258 0x825D 0x8257 0x0252 0x0270 0x8275 0x827F 0x027A 0x826B 0x026E 0x0264 0x8261 -0x0220 0x8225 0x822F 0x022A 0x823B 0x023E 0x0234 0x8231 0x8213 0x0216 0x021C 0x8219 0x0208 0x820D 0x8207 0x0202 \ No newline at end of file diff --git a/src/main/scala/d2dadapter/CRC16_8005_table_result.txt b/src/main/scala/d2dadapter/CRC16_8005_table_result.txt deleted file mode 100644 index d3a2efe..0000000 --- a/src/main/scala/d2dadapter/CRC16_8005_table_result.txt +++ /dev/null @@ -1,32 +0,0 @@ -VecInit(0x0000.U, 0x8005.U, 0x800F.U, 0x000A.U, 0x801B.U, 0x001E.U, 0x0014.U, 0x8011.U, - 0x8033.U, 0x0036.U, 0x003C.U, 0x8039.U, 0x0028.U, 0x802D.U, 0x8027.U, 0x0022.U, - 0x8063.U, 0x0066.U, 0x006C.U, 0x8069.U, 0x0078.U, 0x807D.U, 0x8077.U, 0x0072.U, - 0x0050.U, 0x8055.U, 0x805F.U, 0x005A.U, 0x804B.U, 0x004E.U, 0x0044.U, 0x8041.U, - 0x80C3.U, 0x00C6.U, 0x00CC.U, 0x80C9.U, 0x00D8.U, 0x80DD.U, 0x80D7.U, 0x00D2.U, - 0x00F0.U, 0x80F5.U, 0x80FF.U, 0x00FA.U, 0x80EB.U, 0x00EE.U, 0x00E4.U, 0x80E1.U, - 0x00A0.U, 0x80A5.U, 0x80AF.U, 0x00AA.U, 0x80BB.U, 0x00BE.U, 0x00B4.U, 0x80B1.U, - 0x8093.U, 0x0096.U, 0x009C.U, 0x8099.U, 0x0088.U, 0x808D.U, 0x8087.U, 0x0082.U, - 0x8183.U, 0x0186.U, 0x018C.U, 0x8189.U, 0x0198.U, 0x819D.U, 0x8197.U, 0x0192.U, - 0x01B0.U, 0x81B5.U, 0x81BF.U, 0x01BA.U, 0x81AB.U, 0x01AE.U, 0x01A4.U, 0x81A1.U, - 0x01E0.U, 0x81E5.U, 0x81EF.U, 0x01EA.U, 0x81FB.U, 0x01FE.U, 0x01F4.U, 0x81F1.U, - 0x81D3.U, 0x01D6.U, 0x01DC.U, 0x81D9.U, 0x01C8.U, 0x81CD.U, 0x81C7.U, 0x01C2.U, - 0x0140.U, 0x8145.U, 0x814F.U, 0x014A.U, 0x815B.U, 0x015E.U, 0x0154.U, 0x8151.U, - 0x8173.U, 0x0176.U, 0x017C.U, 0x8179.U, 0x0168.U, 0x816D.U, 0x8167.U, 0x0162.U, - 0x8123.U, 0x0126.U, 0x012C.U, 0x8129.U, 0x0138.U, 0x813D.U, 0x8137.U, 0x0132.U, - 0x0110.U, 0x8115.U, 0x811F.U, 0x011A.U, 0x810B.U, 0x010E.U, 0x0104.U, 0x8101.U, - 0x8303.U, 0x0306.U, 0x030C.U, 0x8309.U, 0x0318.U, 0x831D.U, 0x8317.U, 0x0312.U, - 0x0330.U, 0x8335.U, 0x833F.U, 0x033A.U, 0x832B.U, 0x032E.U, 0x0324.U, 0x8321.U, - 0x0360.U, 0x8365.U, 0x836F.U, 0x036A.U, 0x837B.U, 0x037E.U, 0x0374.U, 0x8371.U, - 0x8353.U, 0x0356.U, 0x035C.U, 0x8359.U, 0x0348.U, 0x834D.U, 0x8347.U, 0x0342.U, - 0x03C0.U, 0x83C5.U, 0x83CF.U, 0x03CA.U, 0x83DB.U, 0x03DE.U, 0x03D4.U, 0x83D1.U, - 0x83F3.U, 0x03F6.U, 0x03FC.U, 0x83F9.U, 0x03E8.U, 0x83ED.U, 0x83E7.U, 0x03E2.U, - 0x83A3.U, 0x03A6.U, 0x03AC.U, 0x83A9.U, 0x03B8.U, 0x83BD.U, 0x83B7.U, 0x03B2.U, - 0x0390.U, 0x8395.U, 0x839F.U, 0x039A.U, 0x838B.U, 0x038E.U, 0x0384.U, 0x8381.U, - 0x0280.U, 0x8285.U, 0x828F.U, 0x028A.U, 0x829B.U, 0x029E.U, 0x0294.U, 0x8291.U, - 0x82B3.U, 0x02B6.U, 0x02BC.U, 0x82B9.U, 0x02A8.U, 0x82AD.U, 0x82A7.U, 0x02A2.U, - 0x82E3.U, 0x02E6.U, 0x02EC.U, 0x82E9.U, 0x02F8.U, 0x82FD.U, 0x82F7.U, 0x02F2.U, - 0x02D0.U, 0x82D5.U, 0x82DF.U, 0x02DA.U, 0x82CB.U, 0x02CE.U, 0x02C4.U, 0x82C1.U, - 0x8243.U, 0x0246.U, 0x024C.U, 0x8249.U, 0x0258.U, 0x825D.U, 0x8257.U, 0x0252.U, - 0x0270.U, 0x8275.U, 0x827F.U, 0x027A.U, 0x826B.U, 0x026E.U, 0x0264.U, 0x8261.U, - 0x0220.U, 0x8225.U, 0x822F.U, 0x022A.U, 0x823B.U, 0x023E.U, 0x0234.U, 0x8231.U, - 0x8213.U, 0x0216.U, 0x021C.U, 0x8219.U, 0x0208.U, 0x820D.U, 0x8207.U, 0x0202.U) diff --git a/src/main/scala/d2dadapter/generate_table.py b/src/main/scala/d2dadapter/generate_table.py deleted file mode 100644 index 516b053..0000000 --- a/src/main/scala/d2dadapter/generate_table.py +++ /dev/null @@ -1,28 +0,0 @@ - -table_name = "src\main\scala\d2dadapter\CRC16_8005_table.txt" - - -with open(table_name, "r") as table_file: - numbers = table_file.read().split() - -result = ['VecInit('] -line = 0 - -for i in range(len(numbers)): - if i > 0 and i % 8 == 0: - result.append(' ') - line += 1 - result[line] += f'{numbers[i]}.U, ' -result[line] = result[line][:-2] -result[line] += ')' - - -result_name = table_name.split('.txt')[0] + "_result.txt" -with open(result_name, "w") as result_file: - for line in result: - result_file.write(line + '\n') - - - - - From 63cd816f3bc46e4791522cc8e7e8bd49af49e85f Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Wed, 1 Nov 2023 10:15:56 -0700 Subject: [PATCH 15/29] Format changes --- .../scala/d2dadapter/CRC16Lookup8Bit.scala | 300 +++++++++++++++--- src/main/scala/d2dadapter/CRCGenerator.scala | 144 +++++---- 2 files changed, 334 insertions(+), 110 deletions(-) diff --git a/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala index 2e68266..63b9ef8 100644 --- a/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala +++ b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala @@ -1,47 +1,267 @@ package edu.berkeley.cs.ucie.digital.d2dadapter import chisel3._ -import chisel3.util._ - class CRC16Lookup { - // Lookup table for CRC-16 (0x8005) polynomial - - val table = VecInit(0x0000.U, 0x8005.U, 0x800F.U, 0x000A.U, 0x801B.U, 0x001E.U, 0x0014.U, 0x8011.U, - 0x8033.U, 0x0036.U, 0x003C.U, 0x8039.U, 0x0028.U, 0x802D.U, 0x8027.U, 0x0022.U, - 0x8063.U, 0x0066.U, 0x006C.U, 0x8069.U, 0x0078.U, 0x807D.U, 0x8077.U, 0x0072.U, - 0x0050.U, 0x8055.U, 0x805F.U, 0x005A.U, 0x804B.U, 0x004E.U, 0x0044.U, 0x8041.U, - 0x80C3.U, 0x00C6.U, 0x00CC.U, 0x80C9.U, 0x00D8.U, 0x80DD.U, 0x80D7.U, 0x00D2.U, - 0x00F0.U, 0x80F5.U, 0x80FF.U, 0x00FA.U, 0x80EB.U, 0x00EE.U, 0x00E4.U, 0x80E1.U, - 0x00A0.U, 0x80A5.U, 0x80AF.U, 0x00AA.U, 0x80BB.U, 0x00BE.U, 0x00B4.U, 0x80B1.U, - 0x8093.U, 0x0096.U, 0x009C.U, 0x8099.U, 0x0088.U, 0x808D.U, 0x8087.U, 0x0082.U, - 0x8183.U, 0x0186.U, 0x018C.U, 0x8189.U, 0x0198.U, 0x819D.U, 0x8197.U, 0x0192.U, - 0x01B0.U, 0x81B5.U, 0x81BF.U, 0x01BA.U, 0x81AB.U, 0x01AE.U, 0x01A4.U, 0x81A1.U, - 0x01E0.U, 0x81E5.U, 0x81EF.U, 0x01EA.U, 0x81FB.U, 0x01FE.U, 0x01F4.U, 0x81F1.U, - 0x81D3.U, 0x01D6.U, 0x01DC.U, 0x81D9.U, 0x01C8.U, 0x81CD.U, 0x81C7.U, 0x01C2.U, - 0x0140.U, 0x8145.U, 0x814F.U, 0x014A.U, 0x815B.U, 0x015E.U, 0x0154.U, 0x8151.U, - 0x8173.U, 0x0176.U, 0x017C.U, 0x8179.U, 0x0168.U, 0x816D.U, 0x8167.U, 0x0162.U, - 0x8123.U, 0x0126.U, 0x012C.U, 0x8129.U, 0x0138.U, 0x813D.U, 0x8137.U, 0x0132.U, - 0x0110.U, 0x8115.U, 0x811F.U, 0x011A.U, 0x810B.U, 0x010E.U, 0x0104.U, 0x8101.U, - 0x8303.U, 0x0306.U, 0x030C.U, 0x8309.U, 0x0318.U, 0x831D.U, 0x8317.U, 0x0312.U, - 0x0330.U, 0x8335.U, 0x833F.U, 0x033A.U, 0x832B.U, 0x032E.U, 0x0324.U, 0x8321.U, - 0x0360.U, 0x8365.U, 0x836F.U, 0x036A.U, 0x837B.U, 0x037E.U, 0x0374.U, 0x8371.U, - 0x8353.U, 0x0356.U, 0x035C.U, 0x8359.U, 0x0348.U, 0x834D.U, 0x8347.U, 0x0342.U, - 0x03C0.U, 0x83C5.U, 0x83CF.U, 0x03CA.U, 0x83DB.U, 0x03DE.U, 0x03D4.U, 0x83D1.U, - 0x83F3.U, 0x03F6.U, 0x03FC.U, 0x83F9.U, 0x03E8.U, 0x83ED.U, 0x83E7.U, 0x03E2.U, - 0x83A3.U, 0x03A6.U, 0x03AC.U, 0x83A9.U, 0x03B8.U, 0x83BD.U, 0x83B7.U, 0x03B2.U, - 0x0390.U, 0x8395.U, 0x839F.U, 0x039A.U, 0x838B.U, 0x038E.U, 0x0384.U, 0x8381.U, - 0x0280.U, 0x8285.U, 0x828F.U, 0x028A.U, 0x829B.U, 0x029E.U, 0x0294.U, 0x8291.U, - 0x82B3.U, 0x02B6.U, 0x02BC.U, 0x82B9.U, 0x02A8.U, 0x82AD.U, 0x82A7.U, 0x02A2.U, - 0x82E3.U, 0x02E6.U, 0x02EC.U, 0x82E9.U, 0x02F8.U, 0x82FD.U, 0x82F7.U, 0x02F2.U, - 0x02D0.U, 0x82D5.U, 0x82DF.U, 0x02DA.U, 0x82CB.U, 0x02CE.U, 0x02C4.U, 0x82C1.U, - 0x8243.U, 0x0246.U, 0x024C.U, 0x8249.U, 0x0258.U, 0x825D.U, 0x8257.U, 0x0252.U, - 0x0270.U, 0x8275.U, 0x827F.U, 0x027A.U, 0x826B.U, 0x026E.U, 0x0264.U, 0x8261.U, - 0x0220.U, 0x8225.U, 0x822F.U, 0x022A.U, 0x823B.U, 0x023E.U, 0x0234.U, 0x8231.U, - 0x8213.U, 0x0216.U, 0x021C.U, 0x8219.U, 0x0208.U, 0x820D.U, 0x8207.U, 0x0202.U) - - - + // Lookup table for CRC-16 (0x8005) polynomial -} \ No newline at end of file + val table = VecInit( + 0x0000.U, + 0x8005.U, + 0x800f.U, + 0x000a.U, + 0x801b.U, + 0x001e.U, + 0x0014.U, + 0x8011.U, + 0x8033.U, + 0x0036.U, + 0x003c.U, + 0x8039.U, + 0x0028.U, + 0x802d.U, + 0x8027.U, + 0x0022.U, + 0x8063.U, + 0x0066.U, + 0x006c.U, + 0x8069.U, + 0x0078.U, + 0x807d.U, + 0x8077.U, + 0x0072.U, + 0x0050.U, + 0x8055.U, + 0x805f.U, + 0x005a.U, + 0x804b.U, + 0x004e.U, + 0x0044.U, + 0x8041.U, + 0x80c3.U, + 0x00c6.U, + 0x00cc.U, + 0x80c9.U, + 0x00d8.U, + 0x80dd.U, + 0x80d7.U, + 0x00d2.U, + 0x00f0.U, + 0x80f5.U, + 0x80ff.U, + 0x00fa.U, + 0x80eb.U, + 0x00ee.U, + 0x00e4.U, + 0x80e1.U, + 0x00a0.U, + 0x80a5.U, + 0x80af.U, + 0x00aa.U, + 0x80bb.U, + 0x00be.U, + 0x00b4.U, + 0x80b1.U, + 0x8093.U, + 0x0096.U, + 0x009c.U, + 0x8099.U, + 0x0088.U, + 0x808d.U, + 0x8087.U, + 0x0082.U, + 0x8183.U, + 0x0186.U, + 0x018c.U, + 0x8189.U, + 0x0198.U, + 0x819d.U, + 0x8197.U, + 0x0192.U, + 0x01b0.U, + 0x81b5.U, + 0x81bf.U, + 0x01ba.U, + 0x81ab.U, + 0x01ae.U, + 0x01a4.U, + 0x81a1.U, + 0x01e0.U, + 0x81e5.U, + 0x81ef.U, + 0x01ea.U, + 0x81fb.U, + 0x01fe.U, + 0x01f4.U, + 0x81f1.U, + 0x81d3.U, + 0x01d6.U, + 0x01dc.U, + 0x81d9.U, + 0x01c8.U, + 0x81cd.U, + 0x81c7.U, + 0x01c2.U, + 0x0140.U, + 0x8145.U, + 0x814f.U, + 0x014a.U, + 0x815b.U, + 0x015e.U, + 0x0154.U, + 0x8151.U, + 0x8173.U, + 0x0176.U, + 0x017c.U, + 0x8179.U, + 0x0168.U, + 0x816d.U, + 0x8167.U, + 0x0162.U, + 0x8123.U, + 0x0126.U, + 0x012c.U, + 0x8129.U, + 0x0138.U, + 0x813d.U, + 0x8137.U, + 0x0132.U, + 0x0110.U, + 0x8115.U, + 0x811f.U, + 0x011a.U, + 0x810b.U, + 0x010e.U, + 0x0104.U, + 0x8101.U, + 0x8303.U, + 0x0306.U, + 0x030c.U, + 0x8309.U, + 0x0318.U, + 0x831d.U, + 0x8317.U, + 0x0312.U, + 0x0330.U, + 0x8335.U, + 0x833f.U, + 0x033a.U, + 0x832b.U, + 0x032e.U, + 0x0324.U, + 0x8321.U, + 0x0360.U, + 0x8365.U, + 0x836f.U, + 0x036a.U, + 0x837b.U, + 0x037e.U, + 0x0374.U, + 0x8371.U, + 0x8353.U, + 0x0356.U, + 0x035c.U, + 0x8359.U, + 0x0348.U, + 0x834d.U, + 0x8347.U, + 0x0342.U, + 0x03c0.U, + 0x83c5.U, + 0x83cf.U, + 0x03ca.U, + 0x83db.U, + 0x03de.U, + 0x03d4.U, + 0x83d1.U, + 0x83f3.U, + 0x03f6.U, + 0x03fc.U, + 0x83f9.U, + 0x03e8.U, + 0x83ed.U, + 0x83e7.U, + 0x03e2.U, + 0x83a3.U, + 0x03a6.U, + 0x03ac.U, + 0x83a9.U, + 0x03b8.U, + 0x83bd.U, + 0x83b7.U, + 0x03b2.U, + 0x0390.U, + 0x8395.U, + 0x839f.U, + 0x039a.U, + 0x838b.U, + 0x038e.U, + 0x0384.U, + 0x8381.U, + 0x0280.U, + 0x8285.U, + 0x828f.U, + 0x028a.U, + 0x829b.U, + 0x029e.U, + 0x0294.U, + 0x8291.U, + 0x82b3.U, + 0x02b6.U, + 0x02bc.U, + 0x82b9.U, + 0x02a8.U, + 0x82ad.U, + 0x82a7.U, + 0x02a2.U, + 0x82e3.U, + 0x02e6.U, + 0x02ec.U, + 0x82e9.U, + 0x02f8.U, + 0x82fd.U, + 0x82f7.U, + 0x02f2.U, + 0x02d0.U, + 0x82d5.U, + 0x82df.U, + 0x02da.U, + 0x82cb.U, + 0x02ce.U, + 0x02c4.U, + 0x82c1.U, + 0x8243.U, + 0x0246.U, + 0x024c.U, + 0x8249.U, + 0x0258.U, + 0x825d.U, + 0x8257.U, + 0x0252.U, + 0x0270.U, + 0x8275.U, + 0x827f.U, + 0x027a.U, + 0x826b.U, + 0x026e.U, + 0x0264.U, + 0x8261.U, + 0x0220.U, + 0x8225.U, + 0x822f.U, + 0x022a.U, + 0x823b.U, + 0x023e.U, + 0x0234.U, + 0x8231.U, + 0x8213.U, + 0x0216.U, + 0x021c.U, + 0x8219.U, + 0x0208.U, + 0x820d.U, + 0x8207.U, + 0x0202.U, + ) +} diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index ce44c44..f52be53 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -5,80 +5,84 @@ import chisel3.util._ import chisel3.util.Decoupled import edu.berkeley.cs.ucie.digital.d2dadapter.CRC16Lookup -// TODO: change variable names to snake_case - - /** Generates the CRC of data using the polynomial x^16 + x^15 + x^2 + 1 - * */ class CRCGenerator(width: Int) extends Module { // width is word size in bits (must be whole number of bytes) - val io = IO(new Bundle { - val rst = Input(Bool()) - - val message = Flipped(Decoupled(Bits(width.W))) - - val crc0_out = Output(UInt(8.W)) // CRC 0 Byte output - val crc1_out = Output(UInt(8.W)) // CRC 1 Byte output - val crc_val = Output(Bool()) // Signal to consumer that data on crc0_out and crc1_out are valid - }) - - // Output data registers - val crc0 = RegInit(UInt(8.W), 0.U) - val crc1 = RegInit(UInt(8.W), 0.U) - - // Output signal registers - val message_ready = RegInit(Bool(), false.B) - val crc_val = RegInit(Bool(), false.B) - - // CRC calculating registers - val step = RegInit(UInt(log2Ceil(width/8+1).W), 0.U) // Store number of bytes in width bits - val message_bits = RegInit(Bits(width.W), 0.U) // Latches full word of data when message_ready and data_val - - // CRC calculating table - val lookup = new CRC16Lookup - - // Propogate output data register - io.crc0_out := crc0 - io.crc1_out := crc1 + val io = IO(new Bundle { + val rst = Input(Bool()) + + val message = Flipped(Decoupled(Bits(width.W))) + + val crc0_out = Output(UInt(8.W)) // CRC 0 Byte output + val crc1_out = Output(UInt(8.W)) // CRC 1 Byte output + val crc_val = Output( + Bool(), + ) // Signal to consumer that data on crc0_out and crc1_out are valid + }) + + // Output data registers + val crc0 = RegInit(UInt(8.W), 0.U) + val crc1 = RegInit(UInt(8.W), 0.U) + + // Output signal registers + val message_ready = RegInit(Bool(), false.B) + val crc_val = RegInit(Bool(), false.B) + + // CRC calculating registers + val step = RegInit( + UInt(log2Ceil(width / 8 + 1).W), + 0.U, + ) // Store number of bytes in width bits + val message_bits = RegInit( + Bits(width.W), + 0.U, + ) // Latches full word of data when message_ready and data_val + + // CRC calculating table + val lookup = new CRC16Lookup + + // Propogate output data register + io.crc0_out := crc0 + io.crc1_out := crc1 + + // Signal Valid and Ready + io.crc_val := crc_val + io.message.ready := message_ready + + // Reset logic + when(io.rst) { + // Reset output data registers + crc0 := 0.U + crc1 := 0.U // Signal Valid and Ready - io.crc_val := crc_val - io.message.ready := message_ready - - // Reset logic - when (io.rst) { - // Reset output data registers - crc0 := 0.U - crc1 := 0.U - - // Signal Valid and Ready - crc_val := true.B - message_ready := true.B - - // Reset CRC calculating registers - step := 0.U - } - - // Latch data on message_ready and data_val - when (io.message.valid & io.message.ready) { - step := (width/8).U // Number of bytes in word - message_bits := io.message.bits - crc_val := false.B - message_ready := false.B - } - - // Computation not finished when step is not 0 - when (step > 0.U) { - crc1 := crc0 ^ lookup.table(crc1 ^ message_bits(width-1, width-8))(15, 8) - crc0 := lookup.table(crc1 ^ message_bits(width-1, width-8))(7, 0) - message_bits := message_bits << 8 - step := step - 1.U - crc_val := false.B - message_ready := false.B - } .otherwise { - crc_val := true.B - message_ready := true.B - } + crc_val := true.B + message_ready := true.B + + // Reset CRC calculating registers + step := 0.U + } + + // Latch data on message_ready and data_val + when(io.message.valid & io.message.ready) { + step := (width / 8).U // Number of bytes in word + message_bits := io.message.bits + crc_val := false.B + message_ready := false.B + } + + // Computation not finished when step is not 0 + when(step > 0.U) { + crc1 := crc0 ^ lookup + .table(crc1 ^ message_bits(width - 1, width - 8))(15, 8) + crc0 := lookup.table(crc1 ^ message_bits(width - 1, width - 8))(7, 0) + message_bits := message_bits << 8 + step := step - 1.U + crc_val := false.B + message_ready := false.B + }.otherwise { + crc_val := true.B + message_ready := true.B + } } - From 7a8e649acd7d217faaeffee778cee90153db6ac2 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Wed, 1 Nov 2023 10:29:23 -0700 Subject: [PATCH 16/29] Format with scalafmtAll --- src/test/scala/d2dadapter/CRCGenerator.scala | 83 +++++++++++--------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/src/test/scala/d2dadapter/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala index a17691c..2acf73a 100644 --- a/src/test/scala/d2dadapter/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -8,7 +8,7 @@ import chiseltest.simulator.WriteVcdAnnotation class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { describe("CRCGenerator, 32-bit messages") { it("should produce h8BC as the 16-bit CRC of hF3D1AB23") { - test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => + test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => c.io.rst.poke(true.B) c.clock.step() c.io.rst.poke(false.B) @@ -19,7 +19,7 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { c.io.message.valid.poke(false.B) c.clock.step() while (c.io.crc_val.peek().litValue != 1) { - c.clock.step() + c.clock.step() } c.io.crc1_out.expect("h08".U) c.io.crc0_out.expect("hBC".U) @@ -27,7 +27,7 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { } it("should produce hD34D as the 16-bit CRC of hB481A391") { - test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => + test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => c.io.rst.poke(true.B) c.clock.step() c.io.rst.poke(false.B) @@ -38,17 +38,18 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { c.io.message.valid.poke(false.B) c.clock.step() while (c.io.crc_val.peek().litValue != 1) { - c.clock.step() + c.clock.step() } c.io.crc1_out.expect("hD3".U) c.io.crc0_out.expect("h4D".U) - } } - it("should produce back to back valid 16-bit CRCs of hF3D1AB23 and hB481A391") { - test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => + it( + "should produce back to back valid 16-bit CRCs of hF3D1AB23 and hB481A391", + ) { + test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => c.io.rst.poke(true.B) c.clock.step() c.io.rst.poke(false.B) @@ -59,7 +60,7 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { c.io.message.valid.poke(false.B) c.clock.step() while (c.io.crc_val.peek().litValue != 1) { - c.clock.step() + c.clock.step() } c.io.crc1_out.expect("h08".U) c.io.crc0_out.expect("hBC".U) @@ -74,7 +75,7 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { c.io.message.valid.poke(false.B) c.clock.step() while (c.io.crc_val.peek().litValue != 1) { - c.clock.step() + c.clock.step() } c.io.crc1_out.expect("hD3".U) c.io.crc0_out.expect("h4D".U) @@ -84,42 +85,46 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { describe("CRCGenerator, 1024-bit messages") { it("should produce h5557 as the 16-bit CRC of he3c3598e...") { - test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.rst.poke(true.B) - c.clock.step() - c.io.rst.poke(false.B) - val num = "he3c3598e_dd1a3be2_d429ad05_2b927c61_c2ba41b6_fc7ac0df_093b5d8b_b754d97d_36b105a3_64fce07b_bc68ccef_3b391448_225bc955_7052a494_49168926_c2429be9_66775914_9bf34300_ceee9ae0_7b681d27_bba8b55f_0eadc080_b0955182_0d8200ce_31a58b25_6c8086f6_d535913e_e7867535_f5e15126_f682f852_0fb831c3_ba7e5b69" - c.io.message.bits.poke((num).U) - c.clock.step() - c.io.message.valid.poke(true.B) - c.clock.step() - c.io.message.valid.poke(false.B) - c.clock.step() - while (c.io.crc_val.peek().litValue != 1) { + test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { + c => + c.io.rst.poke(true.B) + c.clock.step() + c.io.rst.poke(false.B) + val num = + "he3c3598e_dd1a3be2_d429ad05_2b927c61_c2ba41b6_fc7ac0df_093b5d8b_b754d97d_36b105a3_64fce07b_bc68ccef_3b391448_225bc955_7052a494_49168926_c2429be9_66775914_9bf34300_ceee9ae0_7b681d27_bba8b55f_0eadc080_b0955182_0d8200ce_31a58b25_6c8086f6_d535913e_e7867535_f5e15126_f682f852_0fb831c3_ba7e5b69" + c.io.message.bits.poke((num).U) + c.clock.step() + c.io.message.valid.poke(true.B) + c.clock.step() + c.io.message.valid.poke(false.B) + c.clock.step() + while (c.io.crc_val.peek().litValue != 1) { c.clock.step() - } - c.io.crc1_out.expect("h55".U) - c.io.crc0_out.expect("h57".U) + } + c.io.crc1_out.expect("h55".U) + c.io.crc0_out.expect("h57".U) } } it("should produce h5b39 as the 16-bit CRC of h21940141...") { - test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.rst.poke(true.B) - c.clock.step() - c.io.rst.poke(false.B) - val num = "h21940141_94204c5b_66aadb33_39ff52dd_59187e4d_8d7f45a0_92f32508_9fdc1174_62f98566_b5767b24_38ffcf48_dcd48173_0d2d0706_19653a06_a208e4d2_ed55d4a7_6cf0e086_db7be8f6_95d30337_c72e6072_1651c46c_3f9a38dd_50d0b5a9_4a8f23e3_f1915b39_e0570141_22bdfa54_293ad6fe_3ef3d240_ae894873_835dc657_881e5c7d" - c.io.message.bits.poke((num).U) - c.clock.step() - c.io.message.valid.poke(true.B) - c.clock.step() - c.io.message.valid.poke(false.B) - c.clock.step() - while (c.io.crc_val.peek().litValue != 1) { + test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { + c => + c.io.rst.poke(true.B) + c.clock.step() + c.io.rst.poke(false.B) + val num = + "h21940141_94204c5b_66aadb33_39ff52dd_59187e4d_8d7f45a0_92f32508_9fdc1174_62f98566_b5767b24_38ffcf48_dcd48173_0d2d0706_19653a06_a208e4d2_ed55d4a7_6cf0e086_db7be8f6_95d30337_c72e6072_1651c46c_3f9a38dd_50d0b5a9_4a8f23e3_f1915b39_e0570141_22bdfa54_293ad6fe_3ef3d240_ae894873_835dc657_881e5c7d" + c.io.message.bits.poke((num).U) + c.clock.step() + c.io.message.valid.poke(true.B) + c.clock.step() + c.io.message.valid.poke(false.B) + c.clock.step() + while (c.io.crc_val.peek().litValue != 1) { c.clock.step() - } - c.io.crc1_out.expect("h5b".U) - c.io.crc0_out.expect("h39".U) + } + c.io.crc1_out.expect("h5b".U) + c.io.crc0_out.expect("h39".U) } } } From 0b3c70116a8fa18d33173ee0b3cb9d3cd6b6bd1d Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Wed, 1 Nov 2023 13:38:57 -0700 Subject: [PATCH 17/29] Added back-to-back 1024-bit test --- src/test/scala/d2dadapter/CRCGenerator.scala | 132 ++++++++++++++----- 1 file changed, 99 insertions(+), 33 deletions(-) diff --git a/src/test/scala/d2dadapter/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala index 2acf73a..12a8983 100644 --- a/src/test/scala/d2dadapter/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -9,40 +9,39 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { describe("CRCGenerator, 32-bit messages") { it("should produce h8BC as the 16-bit CRC of hF3D1AB23") { test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.rst.poke(true.B) + c.io.reset.poke(true.B) c.clock.step() - c.io.rst.poke(false.B) + c.io.reset.poke(false.B) c.io.message.bits.poke("hF3D1AB23".U) c.clock.step() c.io.message.valid.poke(true.B) c.clock.step() c.io.message.valid.poke(false.B) + c.io.crc.ready.poke(true.B) c.clock.step() - while (c.io.crc_val.peek().litValue != 1) { + while (c.io.crc.valid.peek().litValue != 1) { c.clock.step() } - c.io.crc1_out.expect("h08".U) - c.io.crc0_out.expect("hBC".U) + c.io.crc.bits.expect("h08BC".U) } } it("should produce hD34D as the 16-bit CRC of hB481A391") { test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.rst.poke(true.B) + c.io.reset.poke(true.B) c.clock.step() - c.io.rst.poke(false.B) + c.io.reset.poke(false.B) c.io.message.bits.poke("hB481A391".U) c.clock.step() c.io.message.valid.poke(true.B) c.clock.step() c.io.message.valid.poke(false.B) + c.io.crc.ready.poke(true.B) c.clock.step() - while (c.io.crc_val.peek().litValue != 1) { + while (c.io.crc.valid.peek().litValue != 1) { c.clock.step() } - c.io.crc1_out.expect("hD3".U) - c.io.crc0_out.expect("h4D".U) - + c.io.crc.bits.expect("hD34D".U) } } @@ -50,35 +49,35 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { "should produce back to back valid 16-bit CRCs of hF3D1AB23 and hB481A391", ) { test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.rst.poke(true.B) + c.io.reset.poke(true.B) c.clock.step() - c.io.rst.poke(false.B) + c.io.reset.poke(false.B) c.io.message.bits.poke("hF3D1AB23".U) c.clock.step() c.io.message.valid.poke(true.B) c.clock.step() c.io.message.valid.poke(false.B) + c.io.crc.ready.poke(true.B) c.clock.step() - while (c.io.crc_val.peek().litValue != 1) { + while (c.io.crc.valid.peek().litValue != 1) { c.clock.step() } - c.io.crc1_out.expect("h08".U) - c.io.crc0_out.expect("hBC".U) + c.io.crc.bits.expect("h08BC".U) - c.io.rst.poke(true.B) + c.io.reset.poke(true.B) c.clock.step() - c.io.rst.poke(false.B) + c.io.reset.poke(false.B) c.io.message.bits.poke("hB481A391".U) c.clock.step() c.io.message.valid.poke(true.B) c.clock.step() c.io.message.valid.poke(false.B) + c.io.crc.ready.poke(true.B) c.clock.step() - while (c.io.crc_val.peek().litValue != 1) { + while (c.io.crc.valid.peek().litValue != 1) { c.clock.step() } - c.io.crc1_out.expect("hD3".U) - c.io.crc0_out.expect("h4D".U) + c.io.crc.bits.expect("hD34D".U) } } } @@ -87,44 +86,111 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { it("should produce h5557 as the 16-bit CRC of he3c3598e...") { test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.rst.poke(true.B) + c.io.reset.poke(true.B) c.clock.step() - c.io.rst.poke(false.B) + c.io.reset.poke(false.B) val num = - "he3c3598e_dd1a3be2_d429ad05_2b927c61_c2ba41b6_fc7ac0df_093b5d8b_b754d97d_36b105a3_64fce07b_bc68ccef_3b391448_225bc955_7052a494_49168926_c2429be9_66775914_9bf34300_ceee9ae0_7b681d27_bba8b55f_0eadc080_b0955182_0d8200ce_31a58b25_6c8086f6_d535913e_e7867535_f5e15126_f682f852_0fb831c3_ba7e5b69" + ("he3c3598e_dd1a3be2_d429ad05_2b927c61_" + + "c2ba41b6_fc7ac0df_093b5d8b_b754d97d_" + + "36b105a3_64fce07b_bc68ccef_3b391448_" + + "225bc955_7052a494_49168926_c2429be9_" + + "66775914_9bf34300_ceee9ae0_7b681d27_" + + "bba8b55f_0eadc080_b0955182_0d8200ce_" + + "31a58b25_6c8086f6_d535913e_e7867535_" + + "f5e15126_f682f852_0fb831c3_ba7e5b69") c.io.message.bits.poke((num).U) c.clock.step() c.io.message.valid.poke(true.B) c.clock.step() c.io.message.valid.poke(false.B) + c.io.crc.ready.poke(true.B) c.clock.step() - while (c.io.crc_val.peek().litValue != 1) { + while (c.io.crc.valid.peek().litValue != 1) { c.clock.step() } - c.io.crc1_out.expect("h55".U) - c.io.crc0_out.expect("h57".U) + c.io.crc.bits.expect("h5557".U) } } it("should produce h5b39 as the 16-bit CRC of h21940141...") { test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.rst.poke(true.B) + c.io.reset.poke(true.B) c.clock.step() - c.io.rst.poke(false.B) + c.io.reset.poke(false.B) val num = - "h21940141_94204c5b_66aadb33_39ff52dd_59187e4d_8d7f45a0_92f32508_9fdc1174_62f98566_b5767b24_38ffcf48_dcd48173_0d2d0706_19653a06_a208e4d2_ed55d4a7_6cf0e086_db7be8f6_95d30337_c72e6072_1651c46c_3f9a38dd_50d0b5a9_4a8f23e3_f1915b39_e0570141_22bdfa54_293ad6fe_3ef3d240_ae894873_835dc657_881e5c7d" + "h21940141_94204c5b_66aadb33_39ff52dd_" + + "59187e4d_8d7f45a0_92f32508_9fdc1174_" + + "62f98566_b5767b24_38ffcf48_dcd48173_" + + "0d2d0706_19653a06_a208e4d2_ed55d4a7_" + + "6cf0e086_db7be8f6_95d30337_c72e6072_" + + "1651c46c_3f9a38dd_50d0b5a9_4a8f23e3_" + + "f1915b39_e0570141_22bdfa54_293ad6fe_" + + "3ef3d240_ae894873_835dc657_881e5c7d" c.io.message.bits.poke((num).U) c.clock.step() c.io.message.valid.poke(true.B) c.clock.step() c.io.message.valid.poke(false.B) + c.io.crc.ready.poke(true.B) c.clock.step() - while (c.io.crc_val.peek().litValue != 1) { + while (c.io.crc.valid.peek().litValue != 1) { c.clock.step() } - c.io.crc1_out.expect("h5b".U) - c.io.crc0_out.expect("h39".U) + c.io.crc.bits.expect("h5B39".U) + } + } + + it( + "should produce back to back valid 16-bit CRCs of he3c3598e... and h21940141...", + ) { + test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { c => + c.io.reset.poke(true.B) + c.clock.step() + c.io.reset.poke(false.B) + val num1 = + ("he3c3598e_dd1a3be2_d429ad05_2b927c61_" + + "c2ba41b6_fc7ac0df_093b5d8b_b754d97d_" + + "36b105a3_64fce07b_bc68ccef_3b391448_" + + "225bc955_7052a494_49168926_c2429be9_" + + "66775914_9bf34300_ceee9ae0_7b681d27_" + + "bba8b55f_0eadc080_b0955182_0d8200ce_" + + "31a58b25_6c8086f6_d535913e_e7867535_" + + "f5e15126_f682f852_0fb831c3_ba7e5b69") + c.io.message.bits.poke((num1).U) + c.clock.step() + c.io.message.valid.poke(true.B) + c.clock.step() + c.io.message.valid.poke(false.B) + c.io.crc.ready.poke(true.B) + c.clock.step() + while (c.io.crc.valid.peek().litValue != 1) { + c.clock.step() + } + c.io.crc.bits.expect("h5557".U) + + c.io.reset.poke(true.B) + c.clock.step() + c.io.reset.poke(false.B) + val num2 = "h21940141_94204c5b_66aadb33_39ff52dd_" + + "59187e4d_8d7f45a0_92f32508_9fdc1174_" + + "62f98566_b5767b24_38ffcf48_dcd48173_" + + "0d2d0706_19653a06_a208e4d2_ed55d4a7_" + + "6cf0e086_db7be8f6_95d30337_c72e6072_" + + "1651c46c_3f9a38dd_50d0b5a9_4a8f23e3_" + + "f1915b39_e0570141_22bdfa54_293ad6fe_" + + "3ef3d240_ae894873_835dc657_881e5c7d" + c.io.message.bits.poke((num2).U) + c.clock.step() + c.io.message.valid.poke(true.B) + c.clock.step() + c.io.message.valid.poke(false.B) + c.io.crc.ready.poke(true.B) + c.clock.step() + while (c.io.crc.valid.peek().litValue != 1) { + c.clock.step() + } + c.io.crc.bits.expect("h5B39".U) } } } From 618df0b13ad7e9a694fc49e561cf01e63135a671 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Wed, 1 Nov 2023 13:41:07 -0700 Subject: [PATCH 18/29] Reconfigured CRC 3IO interface, documentation --- src/main/scala/d2dadapter/CRCGenerator.scala | 94 ++++++++++++++------ src/test/scala/d2dadapter/CRCGenerator.scala | 89 +++++++++--------- 2 files changed, 114 insertions(+), 69 deletions(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index f52be53..166046e 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -5,29 +5,69 @@ import chisel3.util._ import chisel3.util.Decoupled import edu.berkeley.cs.ucie.digital.d2dadapter.CRC16Lookup -/** Generates the CRC of data using the polynomial x^16 + x^15 + x^2 + 1 +/** Generates the CRC of data using the polynomial x^16 + x^15 + x^2 + 1. The + * message must be formatted according to the UCIe1.1 spec, and the message + * will be consumed one byte per clock cycle, starting from the MSB to the LSB. + * The calculated 2 byte CRC will be available on the crc ReadyValid3IO + * interface in the raw, un-reversed format as indicated in the UCIe1.1 spec + * (i.e. CRC[15] is the MSB of the crc interface's data bits). + * @param width + * The message size in bits (must be whole number of bytes). UCIe1.1 spec + * will use 1024-bit messages, with shorter messages padded with 0s in MSB + * side. + * @groupdesc Signals + * The input and out controls of the CRCGenerator module */ -class CRCGenerator(width: Int) extends Module { // width is word size in bits (must be whole number of bytes) +class CRCGenerator(width: Int) extends Module { // val io = IO(new Bundle { - val rst = Input(Bool()) + /** Resets the CRCGenerator, and sets the default message ready state high + * and crc valid state low. CRC bits will be cleared to 0. + * @group Signals + */ + val reset = Input(Bool()) + + /** ReadyValid3IO interface to allow consumer to transfer message bits to + * the CRCGenerator. Message bits are latched when message ready and + * message valid are high for the same clock cycle, and then the + * CRCGenerator is locked into the calculation loop. + * + * The CRCGenerator will not accept new messages during the calculation + * loop, nor reflect any changes that occur to the message data bits after + * the message was latched on the ready/valid transfer. + * + * The CRCGenerator will only accept a new message after the CRC data has + * been transfered through the CRC ReadyValid3IO interface. + * @group Signals + */ val message = Flipped(Decoupled(Bits(width.W))) - val crc0_out = Output(UInt(8.W)) // CRC 0 Byte output - val crc1_out = Output(UInt(8.W)) // CRC 1 Byte output - val crc_val = Output( - Bool(), - ) // Signal to consumer that data on crc0_out and crc1_out are valid + /** ReadyValid3IO interface to allow CRCGenerator to transfer crc bits to + * the consumer. CRC will be cleared to 0 and invalid on reset. + * + * Once message bits have been transfered, the CRCGenerator will enter the + * calculation loop, consuming the message data one byte each clock cycle + * until all bytes have been consumed. The CRC data bits on the interface + * willl then become valid with the crc valid signal set high. + * + * The CRC data will remain valid and the CRCGenerator will remain in an + * idle state until the consumer initiates a transfer of the CRC data by + * signaling CRC ready high. After this transfer, the CRC data will become + * invalid and the CRC Generator will signal message ready to accept a new + * message. + * @group Signals + */ + val crc = Decoupled(Bits(16.W)) }) // Output data registers - val crc0 = RegInit(UInt(8.W), 0.U) - val crc1 = RegInit(UInt(8.W), 0.U) + val crc0 = RegInit(Bits(8.W), 0.U) + val crc1 = RegInit(Bits(8.W), 0.U) // Output signal registers - val message_ready = RegInit(Bool(), false.B) - val crc_val = RegInit(Bool(), false.B) + val message_ready = RegInit(Bool(), true.B) + val crc_valid = RegInit(Bool(), false.B) // CRC calculating registers val step = RegInit( @@ -43,21 +83,20 @@ class CRCGenerator(width: Int) extends Module { // width is word size in bits (m val lookup = new CRC16Lookup // Propogate output data register - io.crc0_out := crc0 - io.crc1_out := crc1 + io.crc.bits := Cat(crc1, crc0) - // Signal Valid and Ready - io.crc_val := crc_val + // Propogate crc valid and message ready signal + io.crc.valid := crc_valid io.message.ready := message_ready // Reset logic - when(io.rst) { + when(io.reset) { // Reset output data registers crc0 := 0.U crc1 := 0.U // Signal Valid and Ready - crc_val := true.B + crc_valid := false.B message_ready := true.B // Reset CRC calculating registers @@ -66,9 +105,9 @@ class CRCGenerator(width: Int) extends Module { // width is word size in bits (m // Latch data on message_ready and data_val when(io.message.valid & io.message.ready) { - step := (width / 8).U // Number of bytes in word + step := (width / 8).U // Reset step to number of bytes in word message_bits := io.message.bits - crc_val := false.B + crc_valid := false.B message_ready := false.B } @@ -79,10 +118,15 @@ class CRCGenerator(width: Int) extends Module { // width is word size in bits (m crc0 := lookup.table(crc1 ^ message_bits(width - 1, width - 8))(7, 0) message_bits := message_bits << 8 step := step - 1.U - crc_val := false.B - message_ready := false.B - }.otherwise { - crc_val := true.B - message_ready := true.B + crc_valid := step === 1.U // If next step will be 0, CRC is now valid + } + + /* Idle with crc output valid until consumer initiates transfer of CRC with + * io.crc.ready */ + when(crc_valid) { + if (io.crc.ready == true.B) { + crc_valid := false.B + message_ready := true.B + } } } diff --git a/src/test/scala/d2dadapter/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala index 12a8983..a7eed31 100644 --- a/src/test/scala/d2dadapter/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -144,53 +144,54 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { it( "should produce back to back valid 16-bit CRCs of he3c3598e... and h21940141...", ) { - test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.reset.poke(true.B) - c.clock.step() - c.io.reset.poke(false.B) - val num1 = - ("he3c3598e_dd1a3be2_d429ad05_2b927c61_" + - "c2ba41b6_fc7ac0df_093b5d8b_b754d97d_" + - "36b105a3_64fce07b_bc68ccef_3b391448_" + - "225bc955_7052a494_49168926_c2429be9_" + - "66775914_9bf34300_ceee9ae0_7b681d27_" + - "bba8b55f_0eadc080_b0955182_0d8200ce_" + - "31a58b25_6c8086f6_d535913e_e7867535_" + - "f5e15126_f682f852_0fb831c3_ba7e5b69") - c.io.message.bits.poke((num1).U) - c.clock.step() - c.io.message.valid.poke(true.B) - c.clock.step() - c.io.message.valid.poke(false.B) - c.io.crc.ready.poke(true.B) - c.clock.step() - while (c.io.crc.valid.peek().litValue != 1) { + test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { + c => + c.io.reset.poke(true.B) c.clock.step() - } - c.io.crc.bits.expect("h5557".U) + c.io.reset.poke(false.B) + val num1 = + ("he3c3598e_dd1a3be2_d429ad05_2b927c61_" + + "c2ba41b6_fc7ac0df_093b5d8b_b754d97d_" + + "36b105a3_64fce07b_bc68ccef_3b391448_" + + "225bc955_7052a494_49168926_c2429be9_" + + "66775914_9bf34300_ceee9ae0_7b681d27_" + + "bba8b55f_0eadc080_b0955182_0d8200ce_" + + "31a58b25_6c8086f6_d535913e_e7867535_" + + "f5e15126_f682f852_0fb831c3_ba7e5b69") + c.io.message.bits.poke((num1).U) + c.clock.step() + c.io.message.valid.poke(true.B) + c.clock.step() + c.io.message.valid.poke(false.B) + c.io.crc.ready.poke(true.B) + c.clock.step() + while (c.io.crc.valid.peek().litValue != 1) { + c.clock.step() + } + c.io.crc.bits.expect("h5557".U) - c.io.reset.poke(true.B) - c.clock.step() - c.io.reset.poke(false.B) - val num2 = "h21940141_94204c5b_66aadb33_39ff52dd_" + - "59187e4d_8d7f45a0_92f32508_9fdc1174_" + - "62f98566_b5767b24_38ffcf48_dcd48173_" + - "0d2d0706_19653a06_a208e4d2_ed55d4a7_" + - "6cf0e086_db7be8f6_95d30337_c72e6072_" + - "1651c46c_3f9a38dd_50d0b5a9_4a8f23e3_" + - "f1915b39_e0570141_22bdfa54_293ad6fe_" + - "3ef3d240_ae894873_835dc657_881e5c7d" - c.io.message.bits.poke((num2).U) - c.clock.step() - c.io.message.valid.poke(true.B) - c.clock.step() - c.io.message.valid.poke(false.B) - c.io.crc.ready.poke(true.B) - c.clock.step() - while (c.io.crc.valid.peek().litValue != 1) { + c.io.reset.poke(true.B) c.clock.step() - } - c.io.crc.bits.expect("h5B39".U) + c.io.reset.poke(false.B) + val num2 = "h21940141_94204c5b_66aadb33_39ff52dd_" + + "59187e4d_8d7f45a0_92f32508_9fdc1174_" + + "62f98566_b5767b24_38ffcf48_dcd48173_" + + "0d2d0706_19653a06_a208e4d2_ed55d4a7_" + + "6cf0e086_db7be8f6_95d30337_c72e6072_" + + "1651c46c_3f9a38dd_50d0b5a9_4a8f23e3_" + + "f1915b39_e0570141_22bdfa54_293ad6fe_" + + "3ef3d240_ae894873_835dc657_881e5c7d" + c.io.message.bits.poke((num2).U) + c.clock.step() + c.io.message.valid.poke(true.B) + c.clock.step() + c.io.message.valid.poke(false.B) + c.io.crc.ready.poke(true.B) + c.clock.step() + while (c.io.crc.valid.peek().litValue != 1) { + c.clock.step() + } + c.io.crc.bits.expect("h5B39".U) } } } From 252ed7ef648762285e21ab5999a01f019b8b642f Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Wed, 1 Nov 2023 13:42:31 -0700 Subject: [PATCH 19/29] Fixed documentation typo --- src/main/scala/d2dadapter/CRCGenerator.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index 166046e..66f0407 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -16,7 +16,7 @@ import edu.berkeley.cs.ucie.digital.d2dadapter.CRC16Lookup * will use 1024-bit messages, with shorter messages padded with 0s in MSB * side. * @groupdesc Signals - * The input and out controls of the CRCGenerator module + * The input and output controls of the CRCGenerator module */ class CRCGenerator(width: Int) extends Module { // From b2837fd28a7cf5e82f47e9fe918a7646ba5ac0fb Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Thu, 2 Nov 2023 13:03:06 -0700 Subject: [PATCH 20/29] Reconfigured IO, testing with DecoupledDriver --- src/main/scala/d2dadapter/CRCGenerator.scala | 58 ++----- src/test/scala/d2dadapter/CRCGenerator.scala | 159 ++++++------------- 2 files changed, 64 insertions(+), 153 deletions(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index 66f0407..437eed2 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -2,8 +2,6 @@ package edu.berkeley.cs.ucie.digital.d2dadapter import chisel3._ import chisel3.util._ -import chisel3.util.Decoupled -import edu.berkeley.cs.ucie.digital.d2dadapter.CRC16Lookup /** Generates the CRC of data using the polynomial x^16 + x^15 + x^2 + 1. The * message must be formatted according to the UCIe1.1 spec, and the message @@ -19,16 +17,10 @@ import edu.berkeley.cs.ucie.digital.d2dadapter.CRC16Lookup * The input and output controls of the CRCGenerator module */ -class CRCGenerator(width: Int) extends Module { // +class CRCGenerator(width: Int) extends Module { + assert(width % 8 == 0) val io = IO(new Bundle { - - /** Resets the CRCGenerator, and sets the default message ready state high - * and crc valid state low. CRC bits will be cleared to 0. - * @group Signals - */ - val reset = Input(Bool()) - - /** ReadyValid3IO interface to allow consumer to transfer message bits to + /** ReadyValidIO interface to allow consumer to transfer message bits to * the CRCGenerator. Message bits are latched when message ready and * message valid are high for the same clock cycle, and then the * CRCGenerator is locked into the calculation loop. @@ -43,7 +35,7 @@ class CRCGenerator(width: Int) extends Module { // */ val message = Flipped(Decoupled(Bits(width.W))) - /** ReadyValid3IO interface to allow CRCGenerator to transfer crc bits to + /** ReadyValidIO interface to allow CRCGenerator to transfer crc bits to * the consumer. CRC will be cleared to 0 and invalid on reset. * * Once message bits have been transfered, the CRCGenerator will enter the @@ -70,14 +62,10 @@ class CRCGenerator(width: Int) extends Module { // val crc_valid = RegInit(Bool(), false.B) // CRC calculating registers - val step = RegInit( - UInt(log2Ceil(width / 8 + 1).W), - 0.U, - ) // Store number of bytes in width bits - val message_bits = RegInit( - Bits(width.W), - 0.U, - ) // Latches full word of data when message_ready and data_val + // Store number of bytes in width bits + val step = RegInit(0.U(log2Ceil(width / 8 + 1).W)) + // Latches full message when message_ready and data_val + val message_bits = RegInit(Bits(width.W), 0.U) // CRC calculating table val lookup = new CRC16Lookup @@ -89,32 +77,22 @@ class CRCGenerator(width: Int) extends Module { // io.crc.valid := crc_valid io.message.ready := message_ready - // Reset logic - when(io.reset) { - // Reset output data registers + + // Latch data on message_ready and data_val + when(io.message.fire) { + // Reset logic crc0 := 0.U crc1 := 0.U - - // Signal Valid and Ready crc_valid := false.B - message_ready := true.B - - // Reset CRC calculating registers - step := 0.U - } - // Latch data on message_ready and data_val - when(io.message.valid & io.message.ready) { - step := (width / 8).U // Reset step to number of bytes in word + step := (width / 8).U // Set step to number of bytes in word message_bits := io.message.bits - crc_valid := false.B message_ready := false.B } // Computation not finished when step is not 0 when(step > 0.U) { - crc1 := crc0 ^ lookup - .table(crc1 ^ message_bits(width - 1, width - 8))(15, 8) + crc1 := crc0 ^ lookup.table(crc1 ^ message_bits(width - 1, width - 8))(15, 8) crc0 := lookup.table(crc1 ^ message_bits(width - 1, width - 8))(7, 0) message_bits := message_bits << 8 step := step - 1.U @@ -123,10 +101,8 @@ class CRCGenerator(width: Int) extends Module { // /* Idle with crc output valid until consumer initiates transfer of CRC with * io.crc.ready */ - when(crc_valid) { - if (io.crc.ready == true.B) { - crc_valid := false.B - message_ready := true.B - } + when(io.crc.fire) { + crc_valid := false.B + message_ready := true.B } } diff --git a/src/test/scala/d2dadapter/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala index a7eed31..3762aea 100644 --- a/src/test/scala/d2dadapter/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -9,39 +9,21 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { describe("CRCGenerator, 32-bit messages") { it("should produce h8BC as the 16-bit CRC of hF3D1AB23") { test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.reset.poke(true.B) - c.clock.step() - c.io.reset.poke(false.B) - c.io.message.bits.poke("hF3D1AB23".U) - c.clock.step() - c.io.message.valid.poke(true.B) - c.clock.step() - c.io.message.valid.poke(false.B) - c.io.crc.ready.poke(true.B) - c.clock.step() - while (c.io.crc.valid.peek().litValue != 1) { - c.clock.step() - } - c.io.crc.bits.expect("h08BC".U) + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + c.io.message.enqueueNow("hF3D1AB23".U) + c.io.crc.waitForValid() + c.io.crc.expectDequeueNow("h08BC".U) } } it("should produce hD34D as the 16-bit CRC of hB481A391") { test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.reset.poke(true.B) - c.clock.step() - c.io.reset.poke(false.B) - c.io.message.bits.poke("hB481A391".U) - c.clock.step() - c.io.message.valid.poke(true.B) - c.clock.step() - c.io.message.valid.poke(false.B) - c.io.crc.ready.poke(true.B) - c.clock.step() - while (c.io.crc.valid.peek().litValue != 1) { - c.clock.step() - } - c.io.crc.bits.expect("hD34D".U) + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + c.io.message.enqueueNow("hB481A391".U) + c.io.crc.waitForValid() + c.io.crc.expectDequeueNow("hD34D".U) } } @@ -49,35 +31,16 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { "should produce back to back valid 16-bit CRCs of hF3D1AB23 and hB481A391", ) { test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.reset.poke(true.B) - c.clock.step() - c.io.reset.poke(false.B) - c.io.message.bits.poke("hF3D1AB23".U) - c.clock.step() - c.io.message.valid.poke(true.B) - c.clock.step() - c.io.message.valid.poke(false.B) - c.io.crc.ready.poke(true.B) - c.clock.step() - while (c.io.crc.valid.peek().litValue != 1) { - c.clock.step() - } - c.io.crc.bits.expect("h08BC".U) + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) - c.io.reset.poke(true.B) - c.clock.step() - c.io.reset.poke(false.B) - c.io.message.bits.poke("hB481A391".U) - c.clock.step() - c.io.message.valid.poke(true.B) - c.clock.step() - c.io.message.valid.poke(false.B) - c.io.crc.ready.poke(true.B) - c.clock.step() - while (c.io.crc.valid.peek().litValue != 1) { - c.clock.step() - } - c.io.crc.bits.expect("hD34D".U) + c.io.message.enqueueNow("hF3D1AB23".U) + c.io.crc.waitForValid() + c.io.crc.expectDequeueNow("h08BC".U) + + c.io.message.enqueue("hB481A391".U) + c.io.crc.waitForValid() + c.io.crc.expectDequeueNow("hD34D".U) } } } @@ -86,9 +49,8 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { it("should produce h5557 as the 16-bit CRC of he3c3598e...") { test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.reset.poke(true.B) - c.clock.step() - c.io.reset.poke(false.B) + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) val num = ("he3c3598e_dd1a3be2_d429ad05_2b927c61_" + "c2ba41b6_fc7ac0df_093b5d8b_b754d97d_" + @@ -98,26 +60,17 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { "bba8b55f_0eadc080_b0955182_0d8200ce_" + "31a58b25_6c8086f6_d535913e_e7867535_" + "f5e15126_f682f852_0fb831c3_ba7e5b69") - c.io.message.bits.poke((num).U) - c.clock.step() - c.io.message.valid.poke(true.B) - c.clock.step() - c.io.message.valid.poke(false.B) - c.io.crc.ready.poke(true.B) - c.clock.step() - while (c.io.crc.valid.peek().litValue != 1) { - c.clock.step() - } - c.io.crc.bits.expect("h5557".U) + c.io.message.enqueueNow((num).U) + c.io.crc.waitForValid() + c.io.crc.expectDequeueNow("h5557".U) } } it("should produce h5b39 as the 16-bit CRC of h21940141...") { test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.reset.poke(true.B) - c.clock.step() - c.io.reset.poke(false.B) + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) val num = "h21940141_94204c5b_66aadb33_39ff52dd_" + "59187e4d_8d7f45a0_92f32508_9fdc1174_" + @@ -127,17 +80,9 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { "1651c46c_3f9a38dd_50d0b5a9_4a8f23e3_" + "f1915b39_e0570141_22bdfa54_293ad6fe_" + "3ef3d240_ae894873_835dc657_881e5c7d" - c.io.message.bits.poke((num).U) - c.clock.step() - c.io.message.valid.poke(true.B) - c.clock.step() - c.io.message.valid.poke(false.B) - c.io.crc.ready.poke(true.B) - c.clock.step() - while (c.io.crc.valid.peek().litValue != 1) { - c.clock.step() - } - c.io.crc.bits.expect("h5B39".U) + c.io.message.enqueueNow((num).U) + c.io.crc.waitForValid() + c.io.crc.expectDequeueNow("h5B39".U) } } @@ -146,9 +91,8 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { ) { test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.reset.poke(true.B) - c.clock.step() - c.io.reset.poke(false.B) + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) val num1 = ("he3c3598e_dd1a3be2_d429ad05_2b927c61_" + "c2ba41b6_fc7ac0df_093b5d8b_b754d97d_" + @@ -158,21 +102,10 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { "bba8b55f_0eadc080_b0955182_0d8200ce_" + "31a58b25_6c8086f6_d535913e_e7867535_" + "f5e15126_f682f852_0fb831c3_ba7e5b69") - c.io.message.bits.poke((num1).U) - c.clock.step() - c.io.message.valid.poke(true.B) - c.clock.step() - c.io.message.valid.poke(false.B) - c.io.crc.ready.poke(true.B) - c.clock.step() - while (c.io.crc.valid.peek().litValue != 1) { - c.clock.step() - } - c.io.crc.bits.expect("h5557".U) + c.io.message.enqueueNow((num1).U) + c.io.crc.waitForValid() + c.io.crc.expectDequeueNow("h5557".U) - c.io.reset.poke(true.B) - c.clock.step() - c.io.reset.poke(false.B) val num2 = "h21940141_94204c5b_66aadb33_39ff52dd_" + "59187e4d_8d7f45a0_92f32508_9fdc1174_" + "62f98566_b5767b24_38ffcf48_dcd48173_" + @@ -181,18 +114,20 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { "1651c46c_3f9a38dd_50d0b5a9_4a8f23e3_" + "f1915b39_e0570141_22bdfa54_293ad6fe_" + "3ef3d240_ae894873_835dc657_881e5c7d" - c.io.message.bits.poke((num2).U) - c.clock.step() - c.io.message.valid.poke(true.B) - c.clock.step() - c.io.message.valid.poke(false.B) - c.io.crc.ready.poke(true.B) - c.clock.step() - while (c.io.crc.valid.peek().litValue != 1) { - c.clock.step() - } - c.io.crc.bits.expect("h5B39".U) + c.io.message.enqueue((num2).U) + c.io.crc.waitForValid() + c.io.crc.expectDequeueNow("h5B39".U) } } } + + describe("CRCGenerator, 1023-bit width") { + it("should fail due to invalid width = 1023 % 8 != 0") { + assertThrows[AssertionError] { + test(new CRCGenerator(1023)) { c => + throw new AssertionError + } + } + } + } } From 966ba5e1bfddcb8728cba8b9ed4773dc7d4b07a9 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Thu, 2 Nov 2023 13:03:39 -0700 Subject: [PATCH 21/29] Fixed lookup table docstring --- src/main/scala/d2dadapter/CRC16Lookup8Bit.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala index 63b9ef8..73a3fa1 100644 --- a/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala +++ b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala @@ -4,7 +4,11 @@ import chisel3._ class CRC16Lookup { - // Lookup table for CRC-16 (0x8005) polynomial + /** + * Lookup table for CRC-16 (0x8005) polynomial. + * Consumes message from MSB Byte to LSB Byte and results in CRC[15:0] + * in unreversed format as detailed in UCIe1.1 spec. + */ val table = VecInit( 0x0000.U, @@ -264,4 +268,5 @@ class CRC16Lookup { 0x8207.U, 0x0202.U, ) + } From 5465b4587789fe1d1a20aeef65c859739ecb3280 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Thu, 2 Nov 2023 13:24:18 -0700 Subject: [PATCH 22/29] Fixed with scalafmtAll --- .../scala/d2dadapter/CRC16Lookup8Bit.scala | 11 +++++----- src/main/scala/d2dadapter/CRCGenerator.scala | 21 ++++++++++--------- src/test/scala/d2dadapter/CRCGenerator.scala | 8 +++---- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala index 73a3fa1..60bc0bf 100644 --- a/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala +++ b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala @@ -4,11 +4,10 @@ import chisel3._ class CRC16Lookup { - /** - * Lookup table for CRC-16 (0x8005) polynomial. - * Consumes message from MSB Byte to LSB Byte and results in CRC[15:0] - * in unreversed format as detailed in UCIe1.1 spec. - */ + /** Lookup table for CRC-16 (0x8005) polynomial. Consumes message from MSB + * Byte to LSB Byte and results in CRC[15:0] in unreversed format as detailed + * in UCIe1.1 spec. + */ val table = VecInit( 0x0000.U, @@ -268,5 +267,5 @@ class CRC16Lookup { 0x8207.U, 0x0202.U, ) - + } diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index 437eed2..8388aa4 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -20,10 +20,11 @@ import chisel3.util._ class CRCGenerator(width: Int) extends Module { assert(width % 8 == 0) val io = IO(new Bundle { - /** ReadyValidIO interface to allow consumer to transfer message bits to - * the CRCGenerator. Message bits are latched when message ready and - * message valid are high for the same clock cycle, and then the - * CRCGenerator is locked into the calculation loop. + + /** ReadyValidIO interface to allow consumer to transfer message bits to the + * CRCGenerator. Message bits are latched when message ready and message + * valid are high for the same clock cycle, and then the CRCGenerator is + * locked into the calculation loop. * * The CRCGenerator will not accept new messages during the calculation * loop, nor reflect any changes that occur to the message data bits after @@ -35,8 +36,8 @@ class CRCGenerator(width: Int) extends Module { */ val message = Flipped(Decoupled(Bits(width.W))) - /** ReadyValidIO interface to allow CRCGenerator to transfer crc bits to - * the consumer. CRC will be cleared to 0 and invalid on reset. + /** ReadyValidIO interface to allow CRCGenerator to transfer crc bits to the + * consumer. CRC will be cleared to 0 and invalid on reset. * * Once message bits have been transfered, the CRCGenerator will enter the * calculation loop, consuming the message data one byte each clock cycle @@ -63,9 +64,9 @@ class CRCGenerator(width: Int) extends Module { // CRC calculating registers // Store number of bytes in width bits - val step = RegInit(0.U(log2Ceil(width / 8 + 1).W)) + val step = RegInit(0.U(log2Ceil(width / 8 + 1).W)) // Latches full message when message_ready and data_val - val message_bits = RegInit(Bits(width.W), 0.U) + val message_bits = RegInit(Bits(width.W), 0.U) // CRC calculating table val lookup = new CRC16Lookup @@ -77,7 +78,6 @@ class CRCGenerator(width: Int) extends Module { io.crc.valid := crc_valid io.message.ready := message_ready - // Latch data on message_ready and data_val when(io.message.fire) { // Reset logic @@ -92,7 +92,8 @@ class CRCGenerator(width: Int) extends Module { // Computation not finished when step is not 0 when(step > 0.U) { - crc1 := crc0 ^ lookup.table(crc1 ^ message_bits(width - 1, width - 8))(15, 8) + crc1 := crc0 ^ lookup + .table(crc1 ^ message_bits(width - 1, width - 8))(15, 8) crc0 := lookup.table(crc1 ^ message_bits(width - 1, width - 8))(7, 0) message_bits := message_bits << 8 step := step - 1.U diff --git a/src/test/scala/d2dadapter/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala index 3762aea..8b31dd8 100644 --- a/src/test/scala/d2dadapter/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -123,11 +123,11 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { describe("CRCGenerator, 1023-bit width") { it("should fail due to invalid width = 1023 % 8 != 0") { - assertThrows[AssertionError] { - test(new CRCGenerator(1023)) { c => - throw new AssertionError - } + assertThrows[AssertionError] { + test(new CRCGenerator(1023)) { c => + throw new AssertionError } } + } } } From 2bf4ecba0ce27f08ccd386579508c4860f29f01f Mon Sep 17 00:00:00 2001 From: Ethan Wu Date: Thu, 2 Nov 2023 14:48:01 -0700 Subject: [PATCH 23/29] refactor: make CRC16Lookup an object Since hardware types can only be instantiated inside of a module, the `table` member is made into a parentheses-less method so that the `VecInit` is constructed at the use site. --- src/main/scala/d2dadapter/CRC16Lookup8Bit.scala | 5 ++--- src/main/scala/d2dadapter/CRCGenerator.scala | 7 ++----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala index 60bc0bf..e70f636 100644 --- a/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala +++ b/src/main/scala/d2dadapter/CRC16Lookup8Bit.scala @@ -2,14 +2,13 @@ package edu.berkeley.cs.ucie.digital.d2dadapter import chisel3._ -class CRC16Lookup { +object CRC16Lookup { /** Lookup table for CRC-16 (0x8005) polynomial. Consumes message from MSB * Byte to LSB Byte and results in CRC[15:0] in unreversed format as detailed * in UCIe1.1 spec. */ - - val table = VecInit( + def table = VecInit( 0x0000.U, 0x8005.U, 0x800f.U, diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index 8388aa4..3974ee0 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -68,9 +68,6 @@ class CRCGenerator(width: Int) extends Module { // Latches full message when message_ready and data_val val message_bits = RegInit(Bits(width.W), 0.U) - // CRC calculating table - val lookup = new CRC16Lookup - // Propogate output data register io.crc.bits := Cat(crc1, crc0) @@ -92,9 +89,9 @@ class CRCGenerator(width: Int) extends Module { // Computation not finished when step is not 0 when(step > 0.U) { - crc1 := crc0 ^ lookup + crc1 := crc0 ^ CRC16Lookup .table(crc1 ^ message_bits(width - 1, width - 8))(15, 8) - crc0 := lookup.table(crc1 ^ message_bits(width - 1, width - 8))(7, 0) + crc0 := CRC16Lookup.table(crc1 ^ message_bits(width - 1, width - 8))(7, 0) message_bits := message_bits << 8 step := step - 1.U crc_valid := step === 1.U // If next step will be 0, CRC is now valid From 7f836847ed62b1ebf6070b03bbec5b52cc74b2a8 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Thu, 2 Nov 2023 20:13:41 -0700 Subject: [PATCH 24/29] Fixed error test case --- src/main/scala/d2dadapter/CRCGenerator.scala | 14 ++++++++------ src/test/scala/d2dadapter/CRCGenerator.scala | 4 +--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index 3974ee0..7bf14da 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -54,19 +54,22 @@ class CRCGenerator(width: Int) extends Module { val crc = Decoupled(Bits(16.W)) }) - // Output data registers + // CRC data val crc0 = RegInit(Bits(8.W), 0.U) val crc1 = RegInit(Bits(8.W), 0.U) - // Output signal registers + // Output control signals val message_ready = RegInit(Bool(), true.B) val crc_valid = RegInit(Bool(), false.B) - // CRC calculating registers + // CRC calculating variables // Store number of bytes in width bits val step = RegInit(0.U(log2Ceil(width / 8 + 1).W)) // Latches full message when message_ready and data_val val message_bits = RegInit(Bits(width.W), 0.U) + // Calculate lookup table index from current crc MSB byte and message byte + val lookup_index = Wire(UInt(8.W)) + lookup_index := crc1 ^ message_bits(width - 1, width - 8) // Propogate output data register io.crc.bits := Cat(crc1, crc0) @@ -89,9 +92,8 @@ class CRCGenerator(width: Int) extends Module { // Computation not finished when step is not 0 when(step > 0.U) { - crc1 := crc0 ^ CRC16Lookup - .table(crc1 ^ message_bits(width - 1, width - 8))(15, 8) - crc0 := CRC16Lookup.table(crc1 ^ message_bits(width - 1, width - 8))(7, 0) + crc1 := crc0 ^ CRC16Lookup.table(lookup_index)(15, 8) + crc0 := CRC16Lookup.table(lookup_index)(7, 0) message_bits := message_bits << 8 step := step - 1.U crc_valid := step === 1.U // If next step will be 0, CRC is now valid diff --git a/src/test/scala/d2dadapter/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala index 8b31dd8..bdd2a83 100644 --- a/src/test/scala/d2dadapter/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -124,9 +124,7 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { describe("CRCGenerator, 1023-bit width") { it("should fail due to invalid width = 1023 % 8 != 0") { assertThrows[AssertionError] { - test(new CRCGenerator(1023)) { c => - throw new AssertionError - } + test(new CRCGenerator(1023)) { c => } } } } From 8946b69f2452f2f706613f09185648f6e4405df9 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Wed, 15 Nov 2023 11:00:58 -0800 Subject: [PATCH 25/29] Reconfigured CRC update to one line --- src/main/scala/d2dadapter/CRCGenerator.scala | 32 ++++++++++++-------- src/test/scala/d2dadapter/CRCGenerator.scala | 10 ++++-- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index 7bf14da..00c5ab9 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -17,8 +17,17 @@ import chisel3.util._ * The input and output controls of the CRCGenerator module */ -class CRCGenerator(width: Int) extends Module { - assert(width % 8 == 0) +class CRCGenerator(width:Int, bytes_per_cycle: Int) extends Module { + // TODO: Assert valid bytes_per_cycle + assert(bytes_per_cycle == 1 || + bytes_per_cycle == 2 || + bytes_per_cycle == 4 || + bytes_per_cycle == 8 || + bytes_per_cycle == 16 || + bytes_per_cycle == 32 || + bytes_per_cycle == 64 || + bytes_per_cycle == 128 ) + assert((width/8) % bytes_per_cycle == 0) val io = IO(new Bundle { /** ReadyValidIO interface to allow consumer to transfer message bits to the @@ -55,8 +64,7 @@ class CRCGenerator(width: Int) extends Module { }) // CRC data - val crc0 = RegInit(Bits(8.W), 0.U) - val crc1 = RegInit(Bits(8.W), 0.U) + val crc_calc = RegInit(Bits(16.W), 0.U) // Output control signals val message_ready = RegInit(Bool(), true.B) @@ -65,14 +73,13 @@ class CRCGenerator(width: Int) extends Module { // CRC calculating variables // Store number of bytes in width bits val step = RegInit(0.U(log2Ceil(width / 8 + 1).W)) + val consume_step = RegInit(0.U(log2Ceil(bytes_per_cycle + 1).W)) // Latches full message when message_ready and data_val val message_bits = RegInit(Bits(width.W), 0.U) // Calculate lookup table index from current crc MSB byte and message byte - val lookup_index = Wire(UInt(8.W)) - lookup_index := crc1 ^ message_bits(width - 1, width - 8) // Propogate output data register - io.crc.bits := Cat(crc1, crc0) + io.crc.bits := crc_calc // Propogate crc valid and message ready signal io.crc.valid := crc_valid @@ -81,20 +88,21 @@ class CRCGenerator(width: Int) extends Module { // Latch data on message_ready and data_val when(io.message.fire) { // Reset logic - crc0 := 0.U - crc1 := 0.U + crc_calc := 0.U crc_valid := false.B step := (width / 8).U // Set step to number of bytes in word + consume_step := (bytes_per_cycle).U message_bits := io.message.bits message_ready := false.B } - // Computation not finished when step is not 0 + // Computation not finished when step is not 0 when(step > 0.U) { - crc1 := crc0 ^ CRC16Lookup.table(lookup_index)(15, 8) - crc0 := CRC16Lookup.table(lookup_index)(7, 0) + crc_calc := (crc_calc << 8) ^ CRC16Lookup.table(crc_calc(15, 8) ^ message_bits(width - 1, width - 8)) message_bits := message_bits << 8 + + consume_step := (bytes_per_cycle).U step := step - 1.U crc_valid := step === 1.U // If next step will be 0, CRC is now valid } diff --git a/src/test/scala/d2dadapter/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala index bdd2a83..19b154f 100644 --- a/src/test/scala/d2dadapter/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -6,6 +6,7 @@ import org.scalatest.funspec.AnyFunSpec import chiseltest.simulator.WriteVcdAnnotation class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { + /* describe("CRCGenerator, 32-bit messages") { it("should produce h8BC as the 16-bit CRC of hF3D1AB23") { test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => @@ -44,10 +45,11 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { } } } + */ describe("CRCGenerator, 1024-bit messages") { it("should produce h5557 as the 16-bit CRC of he3c3598e...") { - test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { + test(new CRCGenerator(1024, 1)).withAnnotations(Seq(WriteVcdAnnotation)) { c => c.io.message.initSource().setSourceClock(c.clock) c.io.crc.initSink().setSinkClock(c.clock) @@ -67,7 +69,7 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { } it("should produce h5b39 as the 16-bit CRC of h21940141...") { - test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { + test(new CRCGenerator(1024, 1)).withAnnotations(Seq(WriteVcdAnnotation)) { c => c.io.message.initSource().setSourceClock(c.clock) c.io.crc.initSink().setSinkClock(c.clock) @@ -89,7 +91,7 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { it( "should produce back to back valid 16-bit CRCs of he3c3598e... and h21940141...", ) { - test(new CRCGenerator(1024)).withAnnotations(Seq(WriteVcdAnnotation)) { + test(new CRCGenerator(1024, 1)).withAnnotations(Seq(WriteVcdAnnotation)) { c => c.io.message.initSource().setSourceClock(c.clock) c.io.crc.initSink().setSinkClock(c.clock) @@ -121,6 +123,7 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { } } + /* describe("CRCGenerator, 1023-bit width") { it("should fail due to invalid width = 1023 % 8 != 0") { assertThrows[AssertionError] { @@ -128,4 +131,5 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { } } } + */ } From d6d3b53e74a739bcdd9c5f2dc8886a9e80f6d5cb Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Fri, 17 Nov 2023 21:41:44 -0800 Subject: [PATCH 26/29] Added paramterized bytes consumed per cycle --- src/main/scala/d2dadapter/CRCGenerator.scala | 58 ++-- src/test/scala/d2dadapter/CRCGenerator.scala | 277 ++++++++++++++++--- 2 files changed, 282 insertions(+), 53 deletions(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index 00c5ab9..c2e6890 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -13,21 +13,27 @@ import chisel3.util._ * The message size in bits (must be whole number of bytes). UCIe1.1 spec * will use 1024-bit messages, with shorter messages padded with 0s in MSB * side. + * @param bytes_per_cycle + * The number of bytes of the message to consume per clock cycle. This can be + * adjusted depending on processing requirements of consumer. * @groupdesc Signals * The input and output controls of the CRCGenerator module */ -class CRCGenerator(width:Int, bytes_per_cycle: Int) extends Module { - // TODO: Assert valid bytes_per_cycle - assert(bytes_per_cycle == 1 || - bytes_per_cycle == 2 || - bytes_per_cycle == 4 || - bytes_per_cycle == 8 || - bytes_per_cycle == 16 || - bytes_per_cycle == 32 || - bytes_per_cycle == 64 || - bytes_per_cycle == 128 ) - assert((width/8) % bytes_per_cycle == 0) +class CRCGenerator(width: Int, bytes_per_cycle: Int) extends Module { + assert( + bytes_per_cycle == 1 || + bytes_per_cycle == 2 || + bytes_per_cycle == 4 || + bytes_per_cycle == 8 || + bytes_per_cycle == 16 || + bytes_per_cycle == 32 || + bytes_per_cycle == 64 || + bytes_per_cycle == 128, + ) + assert(width % 8 == 0) + assert((width / 8) >= bytes_per_cycle) + assert((width / 8) % bytes_per_cycle == 0) val io = IO(new Bundle { /** ReadyValidIO interface to allow consumer to transfer message bits to the @@ -71,12 +77,10 @@ class CRCGenerator(width:Int, bytes_per_cycle: Int) extends Module { val crc_valid = RegInit(Bool(), false.B) // CRC calculating variables - // Store number of bytes in width bits - val step = RegInit(0.U(log2Ceil(width / 8 + 1).W)) - val consume_step = RegInit(0.U(log2Ceil(bytes_per_cycle + 1).W)) + // Store number of bytes_per_cycle in width bits + val step = RegInit(0.U(log2Ceil((width / 8) / bytes_per_cycle + 1).W)) // Latches full message when message_ready and data_val val message_bits = RegInit(Bits(width.W), 0.U) - // Calculate lookup table index from current crc MSB byte and message byte // Propogate output data register io.crc.bits := crc_calc @@ -91,18 +95,28 @@ class CRCGenerator(width:Int, bytes_per_cycle: Int) extends Module { crc_calc := 0.U crc_valid := false.B - step := (width / 8).U // Set step to number of bytes in word - consume_step := (bytes_per_cycle).U + step := ((width / 8) / bytes_per_cycle).U // Set step to number of cycles needed for word message_bits := io.message.bits message_ready := false.B } - // Computation not finished when step is not 0 - when(step > 0.U) { - crc_calc := (crc_calc << 8) ^ CRC16Lookup.table(crc_calc(15, 8) ^ message_bits(width - 1, width - 8)) - message_bits := message_bits << 8 + def nextCRC(crc: UInt, message: UInt) = { + (0 until bytes_per_cycle).foldLeft(crc) { + case (crc, byte_num) => { + (crc << 8) ^ CRC16Lookup.table( + crc(15, 8) ^ message( + width - 1 - (8 * byte_num), + width - (8 * (byte_num + 1)), + ), + ) + } + } + } - consume_step := (bytes_per_cycle).U + // Computation not finished when step is not 0 + when(step > 0.U) { + crc_calc := nextCRC(crc_calc, message_bits) + message_bits := message_bits << (8 * bytes_per_cycle) step := step - 1.U crc_valid := step === 1.U // If next step will be 0, CRC is now valid } diff --git a/src/test/scala/d2dadapter/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala index 19b154f..1cdb0f2 100644 --- a/src/test/scala/d2dadapter/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -6,46 +6,140 @@ import org.scalatest.funspec.AnyFunSpec import chiseltest.simulator.WriteVcdAnnotation class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { - /* + + def waitInvalid(c: CRCGenerator, cycles: Int) = { + for (i <- 1 until cycles) { + c.clock.step() + c.io.crc.valid.expect(false.B) + } + c.clock.step() + } + describe("CRCGenerator, 32-bit messages") { it("should produce h8BC as the 16-bit CRC of hF3D1AB23") { - test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.message.initSource().setSourceClock(c.clock) - c.io.crc.initSink().setSinkClock(c.clock) - c.io.message.enqueueNow("hF3D1AB23".U) - c.io.crc.waitForValid() - c.io.crc.expectDequeueNow("h08BC".U) + test(new CRCGenerator(32, 1)).withAnnotations(Seq(WriteVcdAnnotation)) { + c => + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + c.io.message.enqueueNow("hF3D1AB23".U) + waitInvalid(c, 4) + c.io.crc.expectDequeueNow("h08BC".U) } } it("should produce hD34D as the 16-bit CRC of hB481A391") { - test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.message.initSource().setSourceClock(c.clock) - c.io.crc.initSink().setSinkClock(c.clock) - c.io.message.enqueueNow("hB481A391".U) - c.io.crc.waitForValid() - c.io.crc.expectDequeueNow("hD34D".U) + test(new CRCGenerator(32, 1)).withAnnotations(Seq(WriteVcdAnnotation)) { + c => + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + c.io.message.enqueueNow("hB481A391".U) + waitInvalid(c, 4) + c.io.crc.expectDequeueNow("hD34D".U) } } it( "should produce back to back valid 16-bit CRCs of hF3D1AB23 and hB481A391", ) { - test(new CRCGenerator(32)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.io.message.initSource().setSourceClock(c.clock) - c.io.crc.initSink().setSinkClock(c.clock) + test(new CRCGenerator(32, 1)).withAnnotations(Seq(WriteVcdAnnotation)) { + c => + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) - c.io.message.enqueueNow("hF3D1AB23".U) - c.io.crc.waitForValid() - c.io.crc.expectDequeueNow("h08BC".U) + c.io.message.enqueueNow("hF3D1AB23".U) + waitInvalid(c, 4) + c.io.crc.expectDequeueNow("h08BC".U) - c.io.message.enqueue("hB481A391".U) - c.io.crc.waitForValid() - c.io.crc.expectDequeueNow("hD34D".U) + c.io.message.enqueue("hB481A391".U) + waitInvalid(c, 4) + c.io.crc.expectDequeueNow("hD34D".U) + } + } + } + + describe("CRCGenerator, 32-bit messages, 2 bytes/16 bits per cycle") { + it("should produce h8BC as the 16-bit CRC of hF3D1AB23") { + test(new CRCGenerator(32, 2)).withAnnotations(Seq(WriteVcdAnnotation)) { + c => + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + c.io.message.enqueueNow("hF3D1AB23".U) + waitInvalid(c, 2) + c.io.crc.expectDequeueNow("h08BC".U) + } + } + + it("should produce hD34D as the 16-bit CRC of hB481A391") { + test(new CRCGenerator(32, 2)).withAnnotations(Seq(WriteVcdAnnotation)) { + c => + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + c.io.message.enqueueNow("hB481A391".U) + waitInvalid(c, 2) + c.io.crc.expectDequeueNow("hD34D".U) + } + } + + it( + "should produce back to back valid 16-bit CRCs of hF3D1AB23 and hB481A391", + ) { + test(new CRCGenerator(32, 2)).withAnnotations(Seq(WriteVcdAnnotation)) { + c => + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + + c.io.message.enqueueNow("hF3D1AB23".U) + waitInvalid(c, 2) + c.io.crc.expectDequeueNow("h08BC".U) + + c.io.message.enqueue("hB481A391".U) + waitInvalid(c, 2) + c.io.crc.expectDequeueNow("hD34D".U) + } + } + } + + describe("CRCGenerator, 32-bit messages, 4 bytes/32 bits per cycle") { + it("should produce h8BC as the 16-bit CRC of hF3D1AB23") { + test(new CRCGenerator(32, 4)).withAnnotations(Seq(WriteVcdAnnotation)) { + c => + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + c.io.message.enqueueNow("hF3D1AB23".U) + waitInvalid(c, 1) + c.io.crc.expectDequeueNow("h08BC".U) + } + } + + it("should produce hD34D as the 16-bit CRC of hB481A391") { + test(new CRCGenerator(32, 4)).withAnnotations(Seq(WriteVcdAnnotation)) { + c => + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + c.io.message.enqueueNow("hB481A391".U) + waitInvalid(c, 1) + c.io.crc.expectDequeueNow("hD34D".U) + } + } + + it( + "should produce back to back valid 16-bit CRCs of hF3D1AB23 and hB481A391", + ) { + test(new CRCGenerator(32, 4)).withAnnotations(Seq(WriteVcdAnnotation)) { + c => + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + + c.io.message.enqueueNow("hF3D1AB23".U) + waitInvalid(c, 1) + c.io.crc.expectDequeueNow("h08BC".U) + + c.io.message.enqueue("hB481A391".U) + waitInvalid(c, 1) + c.io.crc.expectDequeueNow("hD34D".U) } } } - */ describe("CRCGenerator, 1024-bit messages") { it("should produce h5557 as the 16-bit CRC of he3c3598e...") { @@ -63,7 +157,7 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { "31a58b25_6c8086f6_d535913e_e7867535_" + "f5e15126_f682f852_0fb831c3_ba7e5b69") c.io.message.enqueueNow((num).U) - c.io.crc.waitForValid() + waitInvalid(c, 128) c.io.crc.expectDequeueNow("h5557".U) } } @@ -83,7 +177,7 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { "f1915b39_e0570141_22bdfa54_293ad6fe_" + "3ef3d240_ae894873_835dc657_881e5c7d" c.io.message.enqueueNow((num).U) - c.io.crc.waitForValid() + waitInvalid(c, 128) c.io.crc.expectDequeueNow("h5B39".U) } } @@ -105,7 +199,7 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { "31a58b25_6c8086f6_d535913e_e7867535_" + "f5e15126_f682f852_0fb831c3_ba7e5b69") c.io.message.enqueueNow((num1).U) - c.io.crc.waitForValid() + waitInvalid(c, 128) c.io.crc.expectDequeueNow("h5557".U) val num2 = "h21940141_94204c5b_66aadb33_39ff52dd_" + @@ -117,19 +211,140 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { "f1915b39_e0570141_22bdfa54_293ad6fe_" + "3ef3d240_ae894873_835dc657_881e5c7d" c.io.message.enqueue((num2).U) - c.io.crc.waitForValid() + waitInvalid(c, 128) c.io.crc.expectDequeueNow("h5B39".U) } } } - /* - describe("CRCGenerator, 1023-bit width") { + describe("CRCGenerator, 1024-bit messages, 32 bytes/256 bits per cycle") { + it("should produce h5557 as the 16-bit CRC of he3c3598e...") { + test(new CRCGenerator(1024, 32)) + .withAnnotations(Seq(WriteVcdAnnotation)) { c => + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + val num = + ("he3c3598e_dd1a3be2_d429ad05_2b927c61_" + + "c2ba41b6_fc7ac0df_093b5d8b_b754d97d_" + + "36b105a3_64fce07b_bc68ccef_3b391448_" + + "225bc955_7052a494_49168926_c2429be9_" + + "66775914_9bf34300_ceee9ae0_7b681d27_" + + "bba8b55f_0eadc080_b0955182_0d8200ce_" + + "31a58b25_6c8086f6_d535913e_e7867535_" + + "f5e15126_f682f852_0fb831c3_ba7e5b69") + c.io.message.enqueueNow((num).U) + waitInvalid(c, 4) + c.io.crc.expectDequeueNow("h5557".U) + } + } + + it("should produce h5b39 as the 16-bit CRC of h21940141...") { + test(new CRCGenerator(1024, 32)) + .withAnnotations(Seq(WriteVcdAnnotation)) { c => + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + val num = + "h21940141_94204c5b_66aadb33_39ff52dd_" + + "59187e4d_8d7f45a0_92f32508_9fdc1174_" + + "62f98566_b5767b24_38ffcf48_dcd48173_" + + "0d2d0706_19653a06_a208e4d2_ed55d4a7_" + + "6cf0e086_db7be8f6_95d30337_c72e6072_" + + "1651c46c_3f9a38dd_50d0b5a9_4a8f23e3_" + + "f1915b39_e0570141_22bdfa54_293ad6fe_" + + "3ef3d240_ae894873_835dc657_881e5c7d" + c.io.message.enqueueNow((num).U) + waitInvalid(c, 4) + c.io.crc.expectDequeueNow("h5B39".U) + } + } + + it( + "should produce back to back valid 16-bit CRCs of he3c3598e... and h21940141...", + ) { + test(new CRCGenerator(1024, 32)) + .withAnnotations(Seq(WriteVcdAnnotation)) { c => + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + val num1 = + ("he3c3598e_dd1a3be2_d429ad05_2b927c61_" + + "c2ba41b6_fc7ac0df_093b5d8b_b754d97d_" + + "36b105a3_64fce07b_bc68ccef_3b391448_" + + "225bc955_7052a494_49168926_c2429be9_" + + "66775914_9bf34300_ceee9ae0_7b681d27_" + + "bba8b55f_0eadc080_b0955182_0d8200ce_" + + "31a58b25_6c8086f6_d535913e_e7867535_" + + "f5e15126_f682f852_0fb831c3_ba7e5b69") + c.io.message.enqueueNow((num1).U) + waitInvalid(c, 4) + c.io.crc.expectDequeueNow("h5557".U) + + val num2 = "h21940141_94204c5b_66aadb33_39ff52dd_" + + "59187e4d_8d7f45a0_92f32508_9fdc1174_" + + "62f98566_b5767b24_38ffcf48_dcd48173_" + + "0d2d0706_19653a06_a208e4d2_ed55d4a7_" + + "6cf0e086_db7be8f6_95d30337_c72e6072_" + + "1651c46c_3f9a38dd_50d0b5a9_4a8f23e3_" + + "f1915b39_e0570141_22bdfa54_293ad6fe_" + + "3ef3d240_ae894873_835dc657_881e5c7d" + c.io.message.enqueue((num2).U) + waitInvalid(c, 4) + c.io.crc.expectDequeueNow("h5B39".U) + } + } + } + + describe("CRCGenerator, 1024-bit messages, 128 bytes/1024 bits per cycle") { + it("should produce h5557 as the 16-bit CRC of he3c3598e...") { + test(new CRCGenerator(1024, 128)) + .withAnnotations(Seq(WriteVcdAnnotation)) { c => + c.io.message.initSource().setSourceClock(c.clock) + c.io.crc.initSink().setSinkClock(c.clock) + val num = + ("he3c3598e_dd1a3be2_d429ad05_2b927c61_" + + "c2ba41b6_fc7ac0df_093b5d8b_b754d97d_" + + "36b105a3_64fce07b_bc68ccef_3b391448_" + + "225bc955_7052a494_49168926_c2429be9_" + + "66775914_9bf34300_ceee9ae0_7b681d27_" + + "bba8b55f_0eadc080_b0955182_0d8200ce_" + + "31a58b25_6c8086f6_d535913e_e7867535_" + + "f5e15126_f682f852_0fb831c3_ba7e5b69") + c.io.message.enqueueNow((num).U) + waitInvalid(c, 1) + c.io.crc.expectDequeueNow("h5557".U) + } + } + } + + describe("CRCGenerator, invalid widths and bytes_per_cycle") { it("should fail due to invalid width = 1023 % 8 != 0") { assertThrows[AssertionError] { - test(new CRCGenerator(1023)) { c => } + test(new CRCGenerator(1023, 1)) { c => } + } + } + + it("should fail due to invalid bytes_per_cycle = 3") { + assertThrows[AssertionError] { + test(new CRCGenerator(1024, 3)) { c => } + } + } + + it("should fail due to invalid width = 512 and bytes_per_cycle = 3") { + assertThrows[AssertionError] { + test(new CRCGenerator(512, 3)) { c => } + } + } + + it("should fail due to invalid width = 32 and bytes_per_cycle = 3") { + assertThrows[AssertionError] { + test(new CRCGenerator(32, 3)) { c => } + } + } + + it("should fail due to invalid width = 32 and bytes_per_cycle = 5") { + assertThrows[AssertionError] { + test(new CRCGenerator(32, 5)) { c => } } } } - */ + } From cbeb474d79b414d7782272dd7b25698d3d28ac16 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Wed, 29 Nov 2023 10:21:08 -0800 Subject: [PATCH 27/29] Refactored to only send next-consumed message bits --- src/main/scala/d2dadapter/CRCGenerator.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index c2e6890..b451e82 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -105,8 +105,8 @@ class CRCGenerator(width: Int, bytes_per_cycle: Int) extends Module { case (crc, byte_num) => { (crc << 8) ^ CRC16Lookup.table( crc(15, 8) ^ message( - width - 1 - (8 * byte_num), - width - (8 * (byte_num + 1)), + (8 * bytes_per_cycle) - 1 - (8 * byte_num), + (8 * bytes_per_cycle) - (8 * (byte_num + 1)), ), ) } @@ -115,7 +115,7 @@ class CRCGenerator(width: Int, bytes_per_cycle: Int) extends Module { // Computation not finished when step is not 0 when(step > 0.U) { - crc_calc := nextCRC(crc_calc, message_bits) + crc_calc := nextCRC(crc_calc, message_bits(width - 1, width - (8 * bytes_per_cycle))) message_bits := message_bits << (8 * bytes_per_cycle) step := step - 1.U crc_valid := step === 1.U // If next step will be 0, CRC is now valid From 091cddfaa4bab30df2d3a64bbe287433388c3101 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Wed, 29 Nov 2023 10:25:23 -0800 Subject: [PATCH 28/29] Fixed formatting --- src/main/scala/d2dadapter/CRCGenerator.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index b451e82..f9d5966 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -115,7 +115,10 @@ class CRCGenerator(width: Int, bytes_per_cycle: Int) extends Module { // Computation not finished when step is not 0 when(step > 0.U) { - crc_calc := nextCRC(crc_calc, message_bits(width - 1, width - (8 * bytes_per_cycle))) + crc_calc := nextCRC( + crc_calc, + message_bits(width - 1, width - (8 * bytes_per_cycle)), + ) message_bits := message_bits << (8 * bytes_per_cycle) step := step - 1.U crc_valid := step === 1.U // If next step will be 0, CRC is now valid From 3d4ee4fecf390785cc061a36711f52c41b054603 Mon Sep 17 00:00:00 2001 From: ronitnag04 Date: Thu, 14 Dec 2023 01:37:10 -0800 Subject: [PATCH 29/29] Replaced CRC lookup table with shift, XOR CRC_poly method --- src/main/scala/d2dadapter/CRCGenerator.scala | 22 +++++++------------- src/test/scala/d2dadapter/CRCGenerator.scala | 1 + 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/main/scala/d2dadapter/CRCGenerator.scala b/src/main/scala/d2dadapter/CRCGenerator.scala index f9d5966..2421de4 100644 --- a/src/main/scala/d2dadapter/CRCGenerator.scala +++ b/src/main/scala/d2dadapter/CRCGenerator.scala @@ -71,6 +71,7 @@ class CRCGenerator(width: Int, bytes_per_cycle: Int) extends Module { // CRC data val crc_calc = RegInit(Bits(16.W), 0.U) + val crc_poly = RegInit(Bits((width).W), 0x18005.U << width - 17) // Output control signals val message_ready = RegInit(Bool(), true.B) @@ -100,26 +101,19 @@ class CRCGenerator(width: Int, bytes_per_cycle: Int) extends Module { message_ready := false.B } - def nextCRC(crc: UInt, message: UInt) = { - (0 until bytes_per_cycle).foldLeft(crc) { - case (crc, byte_num) => { - (crc << 8) ^ CRC16Lookup.table( - crc(15, 8) ^ message( - (8 * bytes_per_cycle) - 1 - (8 * byte_num), - (8 * bytes_per_cycle) - (8 * (byte_num + 1)), - ), - ) + def nextCRC(message: UInt) = { + (0 until (bytes_per_cycle * 8)).foldLeft(message) { + case (message, bit_num) => { + Mux(message(width - 1) === 1.U, (message ^ crc_poly) << 1, message << 1) } } } // Computation not finished when step is not 0 when(step > 0.U) { - crc_calc := nextCRC( - crc_calc, - message_bits(width - 1, width - (8 * bytes_per_cycle)), - ) - message_bits := message_bits << (8 * bytes_per_cycle) + val update = nextCRC(message_bits) + message_bits := update + crc_calc := update(width - 1, width - 16) step := step - 1.U crc_valid := step === 1.U // If next step will be 0, CRC is now valid } diff --git a/src/test/scala/d2dadapter/CRCGenerator.scala b/src/test/scala/d2dadapter/CRCGenerator.scala index 1cdb0f2..8462c8d 100644 --- a/src/test/scala/d2dadapter/CRCGenerator.scala +++ b/src/test/scala/d2dadapter/CRCGenerator.scala @@ -55,6 +55,7 @@ class CRCGeneratorTest extends AnyFunSpec with ChiselScalatestTester { c.io.crc.expectDequeueNow("hD34D".U) } } + } describe("CRCGenerator, 32-bit messages, 2 bytes/16 bits per cycle") {