summaryrefslogtreecommitdiff
path: root/src/systemc/tests/systemc/examples
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemc/tests/systemc/examples')
-rw-r--r--src/systemc/tests/systemc/examples/aes/aes.cpp1164
-rw-r--r--src/systemc/tests/systemc/examples/aes/golden/aes.log2
-rw-r--r--src/systemc/tests/systemc/examples/isqrt/golden/isqrt.log2
-rw-r--r--src/systemc/tests/systemc/examples/isqrt/isqrt.cpp247
-rw-r--r--src/systemc/tests/systemc/examples/trie/golden/trie.log2
-rw-r--r--src/systemc/tests/systemc/examples/trie/trie.cpp308
-rw-r--r--src/systemc/tests/systemc/examples/updown/golden/updown.log20
-rw-r--r--src/systemc/tests/systemc/examples/updown/updown.cpp134
8 files changed, 1879 insertions, 0 deletions
diff --git a/src/systemc/tests/systemc/examples/aes/aes.cpp b/src/systemc/tests/systemc/examples/aes/aes.cpp
new file mode 100644
index 000000000..45fc3f869
--- /dev/null
+++ b/src/systemc/tests/systemc/examples/aes/aes.cpp
@@ -0,0 +1,1164 @@
+#include <systemc.h>
+
+#define USE_TABLE 1
+
+#if DEBUG
+void
+Dump_R(char *s, sc_uint<8> X[4][4])
+{
+ printf("%s R\n", s);
+ for(int i = 0; i < 4; i++){
+ printf("|");
+ for(int j = 0; j < 4; j++){
+ printf("%02x|", (int)X[i][j]);
+ }
+ printf("\n");
+ }
+}
+
+void
+Dump_rk(char *s, sc_uint<8> X[11][4][4])
+{
+ printf("%s rk\n", s);
+ for(int i = 0; i < 11; i++){
+ printf("%2d: ", (int)i);
+ for(int j = 0; j < 4; j++){
+ printf("|");
+ for(int k = 0; k < 4; k++){
+ printf("%02x|", (int)X[i][j][k]);
+ }
+ printf(" ");
+ }
+ printf("\n");
+ }
+}
+#endif
+
+SC_MODULE(AES_Base)
+{
+ SC_CTOR(AES_Base) {}
+
+ void AddRoundKey(sc_uint<8> a[4][4], const sc_uint<8> rk[4][4]);
+ sc_uint<8> S_Table(sc_uint<8> a);
+ void SchedKey(sc_uint<8> k[4][4], sc_uint<8> W[11][4][4]);
+};
+
+sc_uint<8>
+AES_Base::S_Table(sc_uint<8> a)
+{
+ sc_uint<8> t;
+#if USE_TABLE
+ {
+ static sc_uint<8> S[256] = {
+ 99, 124, 119, 123, 242, 107, 111, 197,
+ 48, 1, 103, 43, 254, 215, 171, 118,
+ 202, 130, 201, 125, 250, 89, 71, 240,
+ 173, 212, 162, 175, 156, 164, 114, 192,
+ 183, 253, 147, 38, 54, 63, 247, 204,
+ 52, 165, 229, 241, 113, 216, 49, 21,
+ 4, 199, 35, 195, 24, 150, 5, 154,
+ 7, 18, 128, 226, 235, 39, 178, 117,
+ 9, 131, 44, 26, 27, 110, 90, 160,
+ 82, 59, 214, 179, 41, 227, 47, 132,
+ 83, 209, 0, 237, 32, 252, 177, 91,
+ 106, 203, 190, 57, 74, 76, 88, 207,
+ 208, 239, 170, 251, 67, 77, 51, 133,
+ 69, 249, 2, 127, 80, 60, 159, 168,
+ 81, 163, 64, 143, 146, 157, 56, 245,
+ 188, 182, 218, 33, 16, 255, 243, 210,
+ 205, 12, 19, 236, 95, 151, 68, 23,
+ 196, 167, 126, 61, 100, 93, 25, 115,
+ 96, 129, 79, 220, 34, 42, 144, 136,
+ 70, 238, 184, 20, 222, 94, 11, 219,
+ 224, 50, 58, 10, 73, 6, 36, 92,
+ 194, 211, 172, 98, 145, 149, 228, 121,
+ 231, 200, 55, 109, 141, 213, 78, 169,
+ 108, 86, 244, 234, 101, 122, 174, 8,
+ 186, 120, 37, 46, 28, 166, 180, 198,
+ 232, 221, 116, 31, 75, 189, 139, 138,
+ 112, 62, 181, 102, 72, 3, 246, 14,
+ 97, 53, 87, 185, 134, 193, 29, 158,
+ 225, 248, 152, 17, 105, 217, 142, 148,
+ 155, 30, 135, 233, 206, 85, 40, 223,
+ 140, 161, 137, 13, 191, 230, 66, 104,
+ 65, 153, 45, 15, 176, 84, 187, 22,
+ };
+ t = S[a];
+ }
+#else
+#define E(A,B) case A: t = B; break
+ switch(a){
+ E( 0, 99); E( 1,124); E( 2,119); E( 3,123); E( 4,242); E( 5,107);
+ E( 6,111); E( 7,197); E( 8, 48); E( 9, 1); E( 10,103); E( 11, 43);
+ E( 12,254); E( 13,215); E( 14,171); E( 15,118); E( 16,202); E( 17,130);
+ E( 18,201); E( 19,125); E( 20,250); E( 21, 89); E( 22, 71); E( 23,240);
+ E( 24,173); E( 25,212); E( 26,162); E( 27,175); E( 28,156); E( 29,164);
+ E( 30,114); E( 31,192); E( 32,183); E( 33,253); E( 34,147); E( 35, 38);
+ E( 36, 54); E( 37, 63); E( 38,247); E( 39,204); E( 40, 52); E( 41,165);
+ E( 42,229); E( 43,241); E( 44,113); E( 45,216); E( 46, 49); E( 47, 21);
+ E( 48, 4); E( 49,199); E( 50, 35); E( 51,195); E( 52, 24); E( 53,150);
+ E( 54, 5); E( 55,154); E( 56, 7); E( 57, 18); E( 58,128); E( 59,226);
+ E( 60,235); E( 61, 39); E( 62,178); E( 63,117); E( 64, 9); E( 65,131);
+ E( 66, 44); E( 67, 26); E( 68, 27); E( 69,110); E( 70, 90); E( 71,160);
+ E( 72, 82); E( 73, 59); E( 74,214); E( 75,179); E( 76, 41); E( 77,227);
+ E( 78, 47); E( 79,132); E( 80, 83); E( 81,209); E( 82, 0); E( 83,237);
+ E( 84, 32); E( 85,252); E( 86,177); E( 87, 91); E( 88,106); E( 89,203);
+ E( 90,190); E( 91, 57); E( 92, 74); E( 93, 76); E( 94, 88); E( 95,207);
+ E( 96,208); E( 97,239); E( 98,170); E( 99,251); E(100, 67); E(101, 77);
+ E(102, 51); E(103,133); E(104, 69); E(105,249); E(106, 2); E(107,127);
+ E(108, 80); E(109, 60); E(110,159); E(111,168); E(112, 81); E(113,163);
+ E(114, 64); E(115,143); E(116,146); E(117,157); E(118, 56); E(119,245);
+ E(120,188); E(121,182); E(122,218); E(123, 33); E(124, 16); E(125,255);
+ E(126,243); E(127,210); E(128,205); E(129, 12); E(130, 19); E(131,236);
+ E(132, 95); E(133,151); E(134, 68); E(135, 23); E(136,196); E(137,167);
+ E(138,126); E(139, 61); E(140,100); E(141, 93); E(142, 25); E(143,115);
+ E(144, 96); E(145,129); E(146, 79); E(147,220); E(148, 34); E(149, 42);
+ E(150,144); E(151,136); E(152, 70); E(153,238); E(154,184); E(155, 20);
+ E(156,222); E(157, 94); E(158, 11); E(159,219); E(160,224); E(161, 50);
+ E(162, 58); E(163, 10); E(164, 73); E(165, 6); E(166, 36); E(167, 92);
+ E(168,194); E(169,211); E(170,172); E(171, 98); E(172,145); E(173,149);
+ E(174,228); E(175,121); E(176,231); E(177,200); E(178, 55); E(179,109);
+ E(180,141); E(181,213); E(182, 78); E(183,169); E(184,108); E(185, 86);
+ E(186,244); E(187,234); E(188,101); E(189,122); E(190,174); E(191, 8);
+ E(192,186); E(193,120); E(194, 37); E(195, 46); E(196, 28); E(197,166);
+ E(198,180); E(199,198); E(200,232); E(201,221); E(202,116); E(203, 31);
+ E(204, 75); E(205,189); E(206,139); E(207,138); E(208,112); E(209, 62);
+ E(210,181); E(211,102); E(212, 72); E(213, 3); E(214,246); E(215, 14);
+ E(216, 97); E(217, 53); E(218, 87); E(219,185); E(220,134); E(221,193);
+ E(222, 29); E(223,158); E(224,225); E(225,248); E(226,152); E(227, 17);
+ E(228,105); E(229,217); E(230,142); E(231,148); E(232,155); E(233, 30);
+ E(234,135); E(235,233); E(236,206); E(237, 85); E(238, 40); E(239,223);
+ E(240,140); E(241,161); E(242,137); E(243, 13); E(244,191); E(245,230);
+ E(246, 66); E(247,104); E(248, 65); E(249,153); E(250, 45); E(251, 15);
+ E(252,176); E(253, 84); E(254,187); E(255, 22);
+ }
+#undef E
+#endif
+ return(t);
+}
+
+
+void
+AES_Base::AddRoundKey(sc_uint<8> a[4][4], const sc_uint<8> rk[4][4])
+{
+ for( sc_uint<3> i = 0; i < 4; i++){
+ for( sc_uint<3> j = 0; j < 4; j++){
+ a[i][j] = a[i][j] ^ rk[i][j];
+ }
+ }
+}
+
+void
+AES_Base::SchedKey(sc_uint<8> k[4][4], sc_uint<8> W[11][4][4])
+{
+ sc_uint<3> i, j;
+ sc_uint<8> tk[4][4];
+ sc_uint<8> tt;
+ sc_uint<4> t;
+
+ for(j = 0; j < 4; j++){
+ for(i = 0; i < 4; i++){
+ tk[i][j] = k[i][j];
+ }
+ }
+
+ for(j = 0; j < 4; j++){
+ for(i = 0; i < 4; i++){
+ W[0][i][j] = tk[i][j];
+ }
+ }
+
+ for( t = 1; t < 11; t++){
+ for(i = 0; i < 4; i++){
+ tk[i][0] ^= S_Table(tk[(i+1)&3][3]);
+ }
+
+#if USE_TABLE
+ { static sc_uint<8> rcon[11] = {
+ 0x0, /* dummy entry to lineup with t's value */
+ 0x01,
+ 0x02,
+ 0x04,
+ 0x08,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0x1b,
+ 0x36
+ };
+ tt = rcon[t];
+ }
+#else
+ switch(t){
+ case 1: tt = 0x01; break; /* 0000 0001 */
+ case 2: tt = 0x02; break; /* 0000 0010 */
+ case 3: tt = 0x04; break; /* 0000 0100 */
+ case 4: tt = 0x08; break; /* 0000 1000 */
+ case 5: tt = 0x10; break; /* 0001 0000 */
+ case 6: tt = 0x20; break; /* 0010 0000 */
+ case 7: tt = 0x40; break; /* 0100 0000 */
+ case 8: tt = 0x80; break; /* 1000 0000 */
+ case 9: tt = 0x1b; break; /* 0001 1011 */
+ case 10: tt = 0x36; break; /* 0011 0110 */
+ }
+#endif
+
+ tk[0][0] ^= tt;
+
+ for(j = 1; j < 4; j++){
+ for(i = 0; i < 4; i++){
+ tk[i][j] ^= tk[i][j-1];
+ }
+ }
+
+ for(j = 0; j < 4; j++){
+ for(i = 0; i < 4; i++){
+ W[t][i][j] = tk[i][j];
+ }
+ }
+ }
+}
+
+class AES_Decrypt : public AES_Base {
+public:
+ SC_HAS_PROCESS(AES_Decrypt);
+ AES_Decrypt(sc_module_name name,
+ sc_clock& pCLK,
+ sc_signal<bool>& pRST_X,
+ sc_signal<bool>& pIn_req,
+ sc_signal<bool>& pIn_ack,
+ sc_signal<bool>& pIn_cmd,
+ sc_signal<sc_biguint<128> >& pIn_wire,
+ sc_signal<bool>& pOut_req,
+ sc_signal<bool>& pOut_ack,
+ sc_signal<sc_biguint<128> >& pOut_wire
+ ) : AES_Base(name)
+ {
+ CLK(pCLK); RST_X(pRST_X);
+ In_req(pIn_req); In_ack(pIn_ack); In_cmd(pIn_cmd); In_wire(pIn_wire);
+ Out_req(pOut_req); Out_ack(pOut_ack); Out_wire(pOut_wire);
+ SC_CTHREAD(MainThread, this->CLK.pos());
+ reset_signal_is(RST_X,false);
+ }
+
+ sc_in_clk CLK;
+ sc_in<bool> RST_X;
+
+ sc_in<sc_biguint<128> > In_wire;
+ sc_out<bool> In_req;
+ sc_in<bool> In_ack;
+ sc_in<bool> In_cmd;
+
+ sc_out<sc_biguint<128> > Out_wire;
+ sc_in<bool> Out_req;
+ sc_out<bool> Out_ack;
+
+#define LOAD_KEY 0
+#define DECRYPT 1
+ sc_uint<1> cmd;
+
+ sc_uint<8> rk[11][4][4];
+ sc_uint<8> R[4][4];
+
+ void MainThread(void);
+ void Reset(void);
+
+ void Input(void);
+ void Output(void);
+
+ void Decrypt(void);
+
+ void InvMixColumns(sc_uint<8> a[4][4]);
+ void ShiftRows_Right_Rotate(sc_uint<8> a[4][4]);
+ void Substitution_Si(sc_uint<8> a[4][4]);
+ sc_uint<8> Si_Table(sc_uint<8> a);
+
+ sc_uint<8> dmul9(const sc_uint<8> B);
+ sc_uint<8> dmulb(const sc_uint<8> B);
+ sc_uint<8> dmuld(const sc_uint<8> B);
+ sc_uint<8> dmule(const sc_uint<8> B);
+};
+
+void
+AES_Decrypt::Reset(void)
+{
+ In_req = false;
+ Out_ack = false;
+}
+
+void
+AES_Decrypt::Input(void)
+{
+ sc_uint<8> t;
+ sc_biguint<128> t_In_wire;
+
+ (void)wait();
+ In_req = true;
+
+ do { wait(); } while(!In_ack);
+
+ cmd = In_cmd;
+ t_In_wire = In_wire.read();
+
+ /*
+ * no matter whether it's a decrypt
+ * or a key_schedule, get the input pins
+ * into R[][].
+ */
+ for(int i = 0; i < 4; i++){
+ for(int j = 0; j < 4; j++){
+ for( int k = 0; k < 8; k++){
+ t[k] = t_In_wire[(i*4+j)*8+k];
+ }
+ R[i][j] = t;
+ }
+ }
+
+ In_req = false;
+
+ //Dump_R("AES_Descrypt::Input R", R);
+}
+
+void
+AES_Decrypt::Output(void)
+{
+ sc_uint<8> t;
+ sc_biguint<128> t_Out_wire;
+
+ do { (void)wait(); } while(!Out_req);
+
+ /*
+ * if it's a decrypt, drive R[][] onto output pins
+ */
+ if( cmd == DECRYPT){
+ for(int i = 0; i < 4; i++){
+ for(int j = 0; j < 4; j++){
+ t = R[i][j];
+ for( int k = 0; k < 8; k++){
+ t_Out_wire[(i*4+j)*8+k] = t[k];
+ }
+ }
+ }
+ Out_wire.write(t_Out_wire);
+
+ //Dump_R("AES_Descrypt::Output R", R);
+ }
+
+ Out_ack = true;
+ (void)wait();
+ Out_ack = false;
+
+}
+
+void
+AES_Decrypt::MainThread(void)
+{
+ (void)Reset();
+
+ {
+ while(!RST_X)
+ (void)wait();
+ }
+
+ for(;;){
+ (void)Input();
+
+ if( cmd == LOAD_KEY ){
+ /*
+ * take R[][] and expand
+ * it into rk[][][]
+ */
+ (void)SchedKey(R, rk);
+ (void)wait(3);
+
+ //Dump_rk("AES_Descrypt::MainThread rk", rk);
+ } else {
+ /*
+ * take R[][] and rk[][][]
+ * and decrypt the data inplace
+ * into R[][]
+ */
+ (void)Decrypt();
+ (void)wait(12);
+ (void)Output();
+ }
+
+ }
+}
+
+void
+AES_Decrypt::Decrypt(void)
+{
+ (void)AddRoundKey(R,rk[10]);
+ //Dump_R("10: AES_Decrypt::AddRoundKey", R);
+
+ (void)Substitution_Si(R);
+ //printf("%d: ", 10); Dump_R("AES_Decrypt::Substitution_Si", R);
+
+ (void)ShiftRows_Right_Rotate(R);
+ //printf("%d: ", 10); Dump_R("AES_Decrypt::ShiftRows_Right_Rotate", R);
+
+ for(sc_uint<4> i = 9; i > 0; i--){
+ (void)AddRoundKey(R, rk[i]);
+ //printf("%d: ", (int)i); Dump_R("AES_Decrypt::AddRoundKey", R);
+
+ (void)InvMixColumns(R);
+ //printf("%d: ", (int)i); Dump_R("AES_Decrypt::InvMixColums", R);
+
+ (void)Substitution_Si(R);
+ //printf("%d: ", (int)i); Dump_R("AES_Decrypt::Substitution_Si", R);
+
+ (void)ShiftRows_Right_Rotate(R);
+ //printf("%d: ", (int)i); Dump_R("AES_Decrypt::ShiftRows_Right_Rotate", R);
+ }
+
+ (void)AddRoundKey(R, rk[0]);
+ //Dump_R("0: AES_Decrypt::AddRoundKey", R);
+}
+
+sc_uint<8>
+AES_Decrypt::Si_Table(sc_uint<8> a)
+{
+ sc_uint<8> t;
+#if USE_TABLE
+ {
+ static sc_uint<8> Si[256] = {
+ 82, 9, 106, 213, 48, 54, 165, 56,
+ 191, 64, 163, 158, 129, 243, 215, 251,
+ 124, 227, 57, 130, 155, 47, 255, 135,
+ 52, 142, 67, 68, 196, 222, 233, 203,
+ 84, 123, 148, 50, 166, 194, 35, 61,
+ 238, 76, 149, 11, 66, 250, 195, 78,
+ 8, 46, 161, 102, 40, 217, 36, 178,
+ 118, 91, 162, 73, 109, 139, 209, 37,
+ 114, 248, 246, 100, 134, 104, 152, 22,
+ 212, 164, 92, 204, 93, 101, 182, 146,
+ 108, 112, 72, 80, 253, 237, 185, 218,
+ 94, 21, 70, 87, 167, 141, 157, 132,
+ 144, 216, 171, 0, 140, 188, 211, 10,
+ 247, 228, 88, 5, 184, 179, 69, 6,
+ 208, 44, 30, 143, 202, 63, 15, 2,
+ 193, 175, 189, 3, 1, 19, 138, 107,
+ 58, 145, 17, 65, 79, 103, 220, 234,
+ 151, 242, 207, 206, 240, 180, 230, 115,
+ 150, 172, 116, 34, 231, 173, 53, 133,
+ 226, 249, 55, 232, 28, 117, 223, 110,
+ 71, 241, 26, 113, 29, 41, 197, 137,
+ 111, 183, 98, 14, 170, 24, 190, 27,
+ 252, 86, 62, 75, 198, 210, 121, 32,
+ 154, 219, 192, 254, 120, 205, 90, 244,
+ 31, 221, 168, 51, 136, 7, 199, 49,
+ 177, 18, 16, 89, 39, 128, 236, 95,
+ 96, 81, 127, 169, 25, 181, 74, 13,
+ 45, 229, 122, 159, 147, 201, 156, 239,
+ 160, 224, 59, 77, 174, 42, 245, 176,
+ 200, 235, 187, 60, 131, 83, 153, 97,
+ 23, 43, 4, 126, 186, 119, 214, 38,
+ 225, 105, 20, 99, 85, 33, 12, 125,
+ };
+ t = Si[a];
+ }
+#else
+#define E(A,B) case A: t = B; break
+ switch(a){
+ E( 0, 82); E( 1, 9); E( 2,106); E( 3,213); E( 4, 48); E( 5, 54);
+ E( 6,165); E( 7, 56); E( 8,191); E( 9, 64); E( 10,163); E( 11,158);
+ E( 12,129); E( 13,243); E( 14,215); E( 15,251); E( 16,124); E( 17,227);
+ E( 18, 57); E( 19,130); E( 20,155); E( 21, 47); E( 22,255); E( 23,135);
+ E( 24, 52); E( 25,142); E( 26, 67); E( 27, 68); E( 28,196); E( 29,222);
+ E( 30,233); E( 31,203); E( 32, 84); E( 33,123); E( 34,148); E( 35, 50);
+ E( 36,166); E( 37,194); E( 38, 35); E( 39, 61); E( 40,238); E( 41, 76);
+ E( 42,149); E( 43, 11); E( 44, 66); E( 45,250); E( 46,195); E( 47, 78);
+ E( 48, 8); E( 49, 46); E( 50,161); E( 51,102); E( 52, 40); E( 53,217);
+ E( 54, 36); E( 55,178); E( 56,118); E( 57, 91); E( 58,162); E( 59, 73);
+ E( 60,109); E( 61,139); E( 62,209); E( 63, 37); E( 64,114); E( 65,248);
+ E( 66,246); E( 67,100); E( 68,134); E( 69,104); E( 70,152); E( 71, 22);
+ E( 72,212); E( 73,164); E( 74, 92); E( 75,204); E( 76, 93); E( 77,101);
+ E( 78,182); E( 79,146); E( 80,108); E( 81,112); E( 82, 72); E( 83, 80);
+ E( 84,253); E( 85,237); E( 86,185); E( 87,218); E( 88, 94); E( 89, 21);
+ E( 90, 70); E( 91, 87); E( 92,167); E( 93,141); E( 94,157); E( 95,132);
+ E( 96,144); E( 97,216); E( 98,171); E( 99, 0); E(100,140); E(101,188);
+ E(102,211); E(103, 10); E(104,247); E(105,228); E(106, 88); E(107, 5);
+ E(108,184); E(109,179); E(110, 69); E(111, 6); E(112,208); E(113, 44);
+ E(114, 30); E(115,143); E(116,202); E(117, 63); E(118, 15); E(119, 2);
+ E(120,193); E(121,175); E(122,189); E(123, 3); E(124, 1); E(125, 19);
+ E(126,138); E(127,107); E(128, 58); E(129,145); E(130, 17); E(131, 65);
+ E(132, 79); E(133,103); E(134,220); E(135,234); E(136,151); E(137,242);
+ E(138,207); E(139,206); E(140,240); E(141,180); E(142,230); E(143,115);
+ E(144,150); E(145,172); E(146,116); E(147, 34); E(148,231); E(149,173);
+ E(150, 53); E(151,133); E(152,226); E(153,249); E(154, 55); E(155,232);
+ E(156, 28); E(157,117); E(158,223); E(159,110); E(160, 71); E(161,241);
+ E(162, 26); E(163,113); E(164, 29); E(165, 41); E(166,197); E(167,137);
+ E(168,111); E(169,183); E(170, 98); E(171, 14); E(172,170); E(173, 24);
+ E(174,190); E(175, 27); E(176,252); E(177, 86); E(178, 62); E(179, 75);
+ E(180,198); E(181,210); E(182,121); E(183, 32); E(184,154); E(185,219);
+ E(186,192); E(187,254); E(188,120); E(189,205); E(190, 90); E(191,244);
+ E(192, 31); E(193,221); E(194,168); E(195, 51); E(196,136); E(197, 7);
+ E(198,199); E(199, 49); E(200,177); E(201, 18); E(202, 16); E(203, 89);
+ E(204, 39); E(205,128); E(206,236); E(207, 95); E(208, 96); E(209, 81);
+ E(210,127); E(211,169); E(212, 25); E(213,181); E(214, 74); E(215, 13);
+ E(216, 45); E(217,229); E(218,122); E(219,159); E(220,147); E(221,201);
+ E(222,156); E(223,239); E(224,160); E(225,224); E(226, 59); E(227, 77);
+ E(228,174); E(229, 42); E(230,245); E(231,176); E(232,200); E(233,235);
+ E(234,187); E(235, 60); E(236,131); E(237, 83); E(238,153); E(239, 97);
+ E(240, 23); E(241, 43); E(242, 4); E(243,126); E(244,186); E(245,119);
+ E(246,214); E(247, 38); E(248,225); E(249,105); E(250, 20); E(251, 99);
+ E(252, 85); E(253, 33); E(254, 12); E(255,125);
+ }
+#undef E
+#endif
+ return(t);
+}
+void
+AES_Decrypt::Substitution_Si(sc_uint<8> a[4][4])
+{
+ for(sc_uint<3> j = 0; j < 4; j++){
+ for( sc_uint<3> i = 0; i < 4; i++){
+ a[i][j] = Si_Table(a[i][j]);
+ }
+ }
+}
+
+/*
+ * this routine does a rotate right
+ * on each row. the first is rotated 0,
+ * ie, nothing is done. the second row
+ * is roatated by 1, the third row by 2
+ * and the finally row by 3.
+ * ie:
+ *
+ * row0 row1 row2 row3
+ * 0123 0123 0123 0123
+ * |||| |||| |||| ||||
+ * 0123 3012 2301 1230
+ *
+ * this is equivalent to ShiftRows(1,...)
+ * code in the reference C code. it
+ * has been expanded to get rid of the
+ * shifts[][][] array used at run time.
+ */
+void
+AES_Decrypt::ShiftRows_Right_Rotate(sc_uint<8> a[4][4])
+{
+ sc_uint<8> t;
+
+ t = a[1][3];
+ a[1][3] = a[1][2];
+ a[1][2] = a[1][1];
+ a[1][1] = a[1][0];
+ a[1][0] = t;
+
+ t = a[2][0];
+ a[2][0] = a[2][2];
+ a[2][2] = t;
+ t = a[2][1];
+ a[2][1] = a[2][3];
+ a[2][3] = t;
+
+ t = a[3][0];
+ a[3][0] = a[3][1];
+ a[3][1] = a[3][2];
+ a[3][2] = a[3][3];
+ a[3][3] = t;
+
+}
+
+void
+AES_Decrypt::InvMixColumns(sc_uint<8> a[4][4])
+{
+ sc_uint<8> t[4][4];
+
+ for(sc_uint<3> j = 0; j < 4; j++){
+ for( sc_uint<3> i = 0; i < 4; i++){
+ t[i][j] = dmule(a[i][j])
+ ^ dmulb(a[(i + 1) & 3][j])
+ ^ dmuld(a[(i + 2) & 3][j])
+ ^ dmul9(a[(i + 3) & 3][j]);
+ }
+ }
+
+ for(sc_uint<3> j = 0; j < 4; j++){
+ for( sc_uint<3> i = 0; i < 4; i++){
+ a[i][j] = t[i][j];
+ }
+ }
+}
+
+sc_uint<8>
+AES_Decrypt::dmul9(const sc_uint<8> B)
+{
+ sc_uint<8> O;
+
+ O[0] = B[5] ^B[0];
+ O[1] = B[5]^B[6] ^B[1];
+ O[2] = B[6]^B[7] ^B[2];
+ O[3] = B[0]^B[7]^B[5]^B[3];
+ O[4] = B[1]^B[6]^B[5]^B[4];
+ O[5] = B[7]^B[2]^B[6]^B[5];
+ O[6] = B[7]^B[3] ^B[6];
+ O[7] = B[4] ^B[7];
+
+ return(O);
+}
+
+sc_uint<8>
+AES_Decrypt::dmulb(const sc_uint<8> B)
+{
+ sc_uint<8> O;
+
+ O[0] = B[5] ^B[7] ^B[0];
+ O[1] = B[5]^B[6] ^B[0]^B[7] ^B[1];
+ O[2] = B[6]^B[7] ^B[1] ^B[2];
+ O[3] = B[0]^B[5] ^B[2] ^B[3];
+ O[4] = B[1]^B[6]^B[5] ^B[3]^B[7] ^B[4];
+ O[5] = B[7]^B[2]^B[6] ^B[4] ^B[5];
+ O[6] = B[7]^B[3] ^B[5] ^B[6];
+ O[7] = B[4] ^B[6] ^B[7];
+
+ return(O);
+}
+
+sc_uint<8>
+AES_Decrypt::dmuld(const sc_uint<8> B)
+{
+ sc_uint<8> O;
+
+ O[0] = B[5] ^B[6] ^B[0];
+ O[1] = B[5] ^B[7] ^B[1];
+ O[2] = B[6] ^B[0] ^B[2];
+ O[3] = B[0]^B[7]^B[5] ^B[1]^B[6] ^B[3];
+ O[4] = B[1]^B[5] ^B[2]^B[7] ^B[4];
+ O[5] = B[2]^B[6] ^B[3] ^B[5];
+ O[6] = B[7]^B[3] ^B[4] ^B[6];
+ O[7] = B[4] ^B[5] ^B[7];
+
+ return(O);
+}
+
+sc_uint<8>
+AES_Decrypt::dmule(const sc_uint<8> B)
+{
+ sc_uint<8> O;
+
+ O[0] = B[5] ^B[6] ^B[7];
+ O[1] = B[5] ^B[7] ^B[0]^B[7];
+ O[2] = B[6] ^B[0] ^B[1];
+ O[3] = B[0]^B[7]^B[5] ^B[1]^B[6] ^B[2]^B[7];
+ O[4] = B[1]^B[5] ^B[2]^B[7] ^B[3]^B[7];
+ O[5] = B[2]^B[6] ^B[3] ^B[4];
+ O[6] = B[7]^B[3] ^B[4] ^B[5];
+ O[7] = B[4] ^B[5] ^B[6];
+
+ return(O);
+}
+
+class AES_Encrypt : public AES_Base {
+public:
+ SC_HAS_PROCESS(AES_Encrypt);
+ AES_Encrypt(sc_module_name name,
+ sc_clock& pCLK,
+ sc_signal<bool>& pRST_X,
+ sc_signal<bool>& pIn_req,
+ sc_signal<bool>& pIn_ack,
+ sc_signal<bool>& pIn_cmd,
+ sc_signal<sc_biguint<128> >& pIn_wire,
+ sc_signal<bool>& pOut_req,
+ sc_signal<bool>& pOut_ack,
+ sc_signal<sc_biguint<128> >& pOut_wire
+ ) : AES_Base(name)
+ {
+ CLK(pCLK); RST_X(pRST_X);
+ In_req(pIn_req); In_ack(pIn_ack); In_cmd(pIn_cmd); In_wire(pIn_wire);
+ Out_req(pOut_req); Out_ack(pOut_ack); Out_wire(pOut_wire);
+ SC_CTHREAD(MainThread, this->CLK.pos());
+ reset_signal_is(RST_X,false);
+ }
+
+ sc_in_clk CLK;
+ sc_in<bool> RST_X;
+
+ sc_in<sc_biguint<128> > In_wire;
+ sc_out<bool> In_req;
+ sc_in<bool> In_ack;
+ sc_in<bool> In_cmd;
+
+ sc_out<sc_biguint<128> > Out_wire;
+ sc_in<bool> Out_req;
+ sc_out<bool> Out_ack;
+
+#define LOAD_KEY 0
+#define ENCRYPT 1
+ sc_uint<1> cmd;
+ sc_uint<8> rk[11][4][4];
+ sc_uint<8> R[4][4];
+
+ void MainThread(void);
+ void Reset(void);
+
+ void Input(void);
+ void Output(void);
+
+ void Encrypt(void);
+
+ void MixColumns(sc_uint<8> a[4][4]);
+ void ShiftRows_Left_Rotate(sc_uint<8> a[4][4]);
+ void Substitution_S(sc_uint<8> a[4][4]);
+
+ sc_uint<8> dmul2(const sc_uint<8> B);
+ sc_uint<8> dmul3(const sc_uint<8> B);
+};
+
+
+void
+AES_Encrypt::Reset(void)
+{
+ In_req = false;
+ Out_ack = false;
+}
+
+void
+AES_Encrypt::Input(void)
+{
+ sc_biguint<128> t_In_wire;
+ sc_uint<8> t;
+
+ (void)wait();
+ In_req = true;
+
+ do { wait(); } while(!In_ack);
+
+ cmd = In_cmd;
+ t_In_wire = In_wire.read();
+
+ /*
+ * no matter whether it's a decrypt
+ * or a key_schedule, get the input pins
+ * into R[][].
+ */
+ for(int i = 0; i < 4; i++){
+ for(int j = 0; j < 4; j++){
+ for( int k = 0; k < 8; k++){
+ t[k] = t_In_wire[(i*4+j)*8+k];
+ }
+ R[i][j] = t;
+ }
+ }
+
+ In_req = false;
+
+ //Dump_R("AES_Encrypt::Input R", R);
+}
+
+void
+AES_Encrypt::Output(void)
+{
+ sc_biguint<128> t_Out_wire;
+ sc_uint<8> t;
+
+ do { (void)wait(); } while(!Out_req);
+
+ /*
+ * if it's a encrypt, drive R[][] onto output pins
+ */
+ if( cmd == ENCRYPT){
+ for(int i = 0; i < 4; i++){
+ for(int j = 0; j < 4; j++){
+ t = R[i][j];
+ for( int k = 0; k < 8; k++){
+ t_Out_wire[(i*4+j)*8+k] = t[k];
+ }
+ }
+ }
+
+ (void)Out_wire.write(t_Out_wire);
+
+ //Dump_R("AES_Encrypt::Output R", R);
+ }
+
+ Out_ack = true;
+ wait();
+ Out_ack = false;
+
+}
+
+void
+AES_Encrypt::MainThread(void)
+{
+ (void)Reset();
+
+ {
+ while(!RST_X)
+ (void)wait();
+ }
+
+ for(;;){
+ (void)Input();
+
+ if( cmd == LOAD_KEY){
+ /*
+ * take R[][] and expand
+ * it into rk[][][]
+ */
+ (void)SchedKey(R, rk);
+ (void)wait(3);
+ //Dump_rk("AES_Encrypt::MainThread rk", rk);
+ } else {
+ /*
+ * take R[][] and rk[][][]
+ * and encrypt the data inplace
+ * into R[][]
+ */
+ (void)Encrypt();
+ (void)wait(12);
+ (void)Output();
+ }
+ }
+}
+
+void
+AES_Encrypt::Encrypt(void)
+{
+ (void)AddRoundKey(R, rk[0]);
+ //Dump_R("0: AES_Encrypt::AddRoundKey", R);
+
+ for(sc_uint<4> i = 1; i < 10; i++){
+ (void)Substitution_S(R);
+ //printf("%d: ", (int)i); Dump_R("AES_Encrypt::Substitution_S", R);
+
+ (void)ShiftRows_Left_Rotate(R);
+ //printf("%d: ", (int)i); Dump_R("AES_Encrypt::ShiftRows_Left_Rotate", R);
+
+ (void)MixColumns(R);
+ //printf("%d: ", (int)i); Dump_R("AES_Encrypt::MixColums", R);
+
+ (void)AddRoundKey(R, rk[i]);
+ //printf("%d: ", (int)i); Dump_R("AES_Encrypt::AddRoundKey", R);
+ }
+
+ (void)Substitution_S(R);
+ //printf("%d: ", 10); Dump_R("AES_Encrypt::Substitution_S", R);
+
+ (void)ShiftRows_Left_Rotate(R);
+ //printf("%d: ", 10); Dump_R("AES_Encrypt::ShiftRows_Left_Rotate", R);
+
+ (void)AddRoundKey(R,rk[10]);
+ //printf("%d: ", 10); Dump_R("AES_Encrypt::AddRoundKey", R);
+}
+
+
+void
+AES_Encrypt::Substitution_S(sc_uint<8> a[4][4])
+{
+ for(sc_uint<3> j = 0; j < 4; j++){
+ for( sc_uint<3> i = 0; i < 4; i++){
+ a[i][j] = S_Table(a[i][j]);
+ }
+ }
+}
+
+/*
+ * this routine does a rotate left
+ * on each row. the first is rotated 0,
+ * ie, nothing is done. the second row
+ * is roatated by 1, the third row by 2
+ * and the finally row by 3.
+ * ie:
+ *
+ * row0 row1 row2 row3
+ * 0123 0123 0123 0123
+ * |||| |||| |||| ||||
+ * 0123 1230 2301 3012
+ *
+ * this is equivalent to ShiftRows(0,...)
+ * code in the reference C code. it
+ * has been expanded to get rid of the
+ * shifts[][][] array used at run time.
+ */
+void
+AES_Encrypt::ShiftRows_Left_Rotate(sc_uint<8> a[4][4])
+{
+ sc_uint<8> t;
+
+ t = a[1][0];
+ a[1][0] = a[1][1];
+ a[1][1] = a[1][2];
+ a[1][2] = a[1][3];
+ a[1][3] = t;
+
+ t = a[2][0];
+ a[2][0] = a[2][2];
+ a[2][2] = t;
+ t = a[2][1];
+ a[2][1] = a[2][3];
+ a[2][3] = t;
+
+ t = a[3][3];
+ a[3][3] = a[3][2];
+ a[3][2] = a[3][1];
+ a[3][1] = a[3][0];
+ a[3][0] = t;
+}
+
+void
+AES_Encrypt::MixColumns(sc_uint<8> a[4][4])
+{
+ sc_uint<8> t[4][4];
+
+ for(sc_uint<3> j = 0; j < 4; j++){
+ for( sc_uint<3> i = 0; i < 4; i++){
+ t[i][j] = dmul2(a[i][j])
+ ^ dmul3(a[(i + 1) & 3][j])
+ ^ a[(i + 2) & 3][j]
+ ^ a[(i + 3) & 3][j];
+
+ }
+ }
+
+ for(sc_uint<3> j = 0; j < 4; j++){
+ for( sc_uint<3> i = 0; i < 4; i++){
+ a[i][j] = t[i][j];
+ }
+ }
+}
+
+
+
+sc_uint<8>
+AES_Encrypt::dmul2(const sc_uint<8> B)
+{
+ sc_uint<8> O;
+
+ O[0] = B[7];
+ O[1] = B[0]^B[7];
+ O[2] = B[1];
+ O[3] = B[2]^B[7];
+ O[4] = B[3]^B[7];
+ O[5] = B[4];
+ O[6] = B[5];
+ O[7] = B[6];
+
+ return(O);
+}
+
+sc_uint<8>
+AES_Encrypt::dmul3(const sc_uint<8> B)
+{
+ sc_uint<8> O;
+
+ O[0] = B[7] ^B[0];
+ O[1] = B[0]^B[7]^B[1];
+ O[2] = B[1] ^B[2];
+ O[3] = B[2]^B[7]^B[3];
+ O[4] = B[3]^B[7]^B[4];
+ O[5] = B[4] ^B[5];
+ O[6] = B[5] ^B[6];
+ O[7] = B[6] ^B[7];
+
+ return(O);
+}
+
+#define TESTBENCH 1
+#if TESTBENCH
+
+sc_biguint<128>
+str2biguint(char *s)
+{
+ static sc_biguint<128> a;
+ char str[16];
+ int i, c;
+
+ for(i = 0; i < 16 && *s != '\0'; i++, s++)
+ str[i] = *s;
+
+ while( i < 16)
+ str[i++] = ' ';
+
+ for(i = 0; i < 16; i++){
+ c = str[i];
+ a[(i*8)+0] = (c&1);
+ a[(i*8)+1] = ((c>>1)&1);
+ a[(i*8)+2] = ((c>>2)&1);
+ a[(i*8)+3] = ((c>>3)&1);
+ a[(i*8)+4] = ((c>>4)&1);
+ a[(i*8)+5] = ((c>>5)&1);
+ a[(i*8)+6] = ((c>>6)&1);
+ a[(i*8)+7] = ((c>>7)&1);
+ }
+
+ return(a);
+}
+
+char *
+biguint2str(sc_biguint<128> a)
+{
+ static char str[17];
+ int i;
+ char c;
+
+ str[16] = '\0';
+
+ for( i = 0; i < 128; i += 8){
+ c = 0;
+ c |= a[i+0] ? 1 : 0;
+ c |= a[i+1] ? 1<<1 : 0;
+ c |= a[i+2] ? 1<<2 : 0;
+ c |= a[i+3] ? 1<<3 : 0;
+ c |= a[i+4] ? 1<<4 : 0;
+ c |= a[i+5] ? 1<<5 : 0;
+ c |= a[i+6] ? 1<<6 : 0;
+ c |= a[i+7] ? 1<<7 : 0;
+ str[i/8] = c;
+
+ }
+
+ return(&str[0]);
+}
+
+sc_biguint<128>
+makekey(char *keyMaterial)
+{
+ int i, j, t, k;
+ sc_uint<8> R[4][4];
+ sc_uint<8> tt;
+ sc_biguint<128> key;
+
+ for(i = 0; i < 128/8; i++) {
+ t = keyMaterial[2*i];
+ if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
+ else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4;
+ else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4;
+ else abort();
+
+ t = keyMaterial[2*i+1];
+ if ((t >= '0') && (t <= '9')) j ^= (t - '0');
+ else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10);
+ else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10);
+ else abort();
+
+ R[i % 4][i / 4] = j;
+ }
+
+ for(i = 0; i < 4; i++){
+ for(j = 0; j < 4; j++){
+ tt = R[i][j];
+ for(k = 0; k < 8; k++){
+ key[(i*4+j)*8+k] = tt[k];
+ }
+ }
+ }
+ return(key);
+}
+
+
+int
+sc_main(int argc, char *argv[])
+{
+ sc_clock clock;
+ sc_signal<bool> reset;
+ sc_signal<bool> D_In_req;
+ sc_signal<bool> D_In_ack;
+ sc_signal<bool> D_In_cmd;
+ sc_signal<bool> D_Out_req;
+ sc_signal<bool> D_Out_ack;
+ sc_signal<sc_biguint<128> > D_In_wire;
+ sc_signal<sc_biguint<128> > D_Out_wire;
+ sc_signal<bool> E_In_req;
+ sc_signal<bool> E_In_ack;
+ sc_signal<bool> E_In_cmd;
+ sc_signal<bool> E_Out_req;
+ sc_signal<bool> E_Out_ack;
+ sc_signal<sc_biguint<128> > E_In_wire;
+ sc_signal<sc_biguint<128> > E_Out_wire;
+ sc_biguint<128> key;
+ sc_biguint<128> t;
+ char *s;
+ char key_string[33] = "deadbeef0123456776543210beefdead";
+ char in[17] = "abcdefghijklmnop";
+ char *out;
+ bool err;
+ int i;
+
+ AES_Encrypt E("AES_Encrypt",
+ clock,
+ reset,
+ E_In_req,
+ E_In_ack,
+ E_In_cmd,
+ E_In_wire,
+ E_Out_req,
+ E_Out_ack,
+ E_Out_wire);
+
+ AES_Decrypt D("AES_Decrypt",
+ clock,
+ reset,
+ D_In_req,
+ D_In_ack,
+ D_In_cmd,
+ D_In_wire,
+ D_Out_req,
+ D_Out_ack,
+ D_Out_wire);
+
+
+ key = makekey(key_string);
+
+ reset = 0;
+ sc_start(2, SC_NS);
+ reset = 1;
+ sc_start(2, SC_NS);
+
+ while( !E_In_req) sc_start(1, SC_NS);
+ E_In_cmd = LOAD_KEY;
+ E_In_ack = 1;
+ E_In_wire = key;
+ do { sc_start(1, SC_NS); E_In_ack = 0; } while( !E_In_req);
+
+ while( !D_In_req) sc_start(1, SC_NS);
+ D_In_cmd = LOAD_KEY;
+ D_In_ack = 1;
+ D_In_wire = key;
+ do { sc_start(1, SC_NS); D_In_ack = 0; } while( !D_In_req);
+
+
+ while( !E_In_req) sc_start(1, SC_NS);
+ E_Out_req = 1;
+ E_In_cmd = ENCRYPT;
+ E_In_ack = 1;
+ E_In_wire = str2biguint((char*)"abcdefghijklmnop");
+ do { sc_start(1, SC_NS); E_In_ack = 0; } while(!E_Out_ack);
+ E_Out_req = 0;
+ sc_start(1, SC_NS);
+
+ while( !D_In_req) sc_start(1, SC_NS);
+ D_Out_req = 1;
+ D_In_cmd = DECRYPT;
+ D_In_ack = 1;
+ D_In_wire = E_Out_wire;
+ do { sc_start(1, SC_NS); D_In_ack = 0; } while(!D_Out_ack);
+ out = biguint2str(D_Out_wire);
+ D_Out_req = 0;
+ sc_start(1, SC_NS);
+
+ err = false;
+ for(i = 0; i < 16; i++){
+ if( in[i] != out[i]){
+ err = true;
+ break;
+ }
+ }
+
+ if( err){
+ cout << "mismatch error at index " << i << endl;
+ cout << "key:" << key_string << " in:" << in
+ << " out:" << out << endl;
+ } else {
+ cout << "program complete" << endl;
+ }
+
+ return(0);
+}
+#endif
+
+
diff --git a/src/systemc/tests/systemc/examples/aes/golden/aes.log b/src/systemc/tests/systemc/examples/aes/golden/aes.log
new file mode 100644
index 000000000..f0fa7a911
--- /dev/null
+++ b/src/systemc/tests/systemc/examples/aes/golden/aes.log
@@ -0,0 +1,2 @@
+SystemC Simulation
+program complete
diff --git a/src/systemc/tests/systemc/examples/isqrt/golden/isqrt.log b/src/systemc/tests/systemc/examples/isqrt/golden/isqrt.log
new file mode 100644
index 000000000..2fd694f12
--- /dev/null
+++ b/src/systemc/tests/systemc/examples/isqrt/golden/isqrt.log
@@ -0,0 +1,2 @@
+SystemC Simulation
+Program completed.
diff --git a/src/systemc/tests/systemc/examples/isqrt/isqrt.cpp b/src/systemc/tests/systemc/examples/isqrt/isqrt.cpp
new file mode 100644
index 000000000..925c7f181
--- /dev/null
+++ b/src/systemc/tests/systemc/examples/isqrt/isqrt.cpp
@@ -0,0 +1,247 @@
+//#include <stdio.h>
+#include "systemc.h"
+
+SC_MODULE(isq)
+{
+ sc_in<bool> RSTN;
+ sc_in_clk CLK;
+
+ sc_out<bool> DIN_rdy;
+ sc_in<bool> DIN_vld;
+ sc_in<sc_uint<18> > DIN_value;
+ sc_in<bool> DOUT_rdy;
+ sc_out<bool> DOUT_vld;
+ sc_out<sc_uint<10> > DOUT_value;
+
+ void thread();
+ sc_uint<10> isqrt5(sc_uint<18>);
+
+ SC_CTOR(isq){
+ SC_CTHREAD(thread, CLK.pos());
+ reset_signal_is(RSTN,false);
+ }
+};
+
+void
+isq::thread()
+{
+ if( !RSTN){
+ DIN_rdy = 1;
+ DOUT_vld = 0;
+ wait(1);
+ }
+
+ for(;;){
+ sc_uint<18> in_value;
+ sc_uint<10> out_value;
+
+ in_value = DIN_value.read();
+ while( !DIN_vld.read()){
+ wait(1);
+ in_value = DIN_value.read();
+ }
+ DIN_rdy = 0;
+ wait(1);
+
+ out_value = isqrt5(in_value);
+
+ while( !DOUT_rdy.read()){
+ wait(1);
+ }
+ DOUT_vld = 1;
+ DOUT_value.write(out_value);
+ DIN_rdy = 1;
+ wait(1);
+ DOUT_vld = 0;
+ }
+}
+
+
+sc_uint<10>
+isq::isqrt5(sc_uint<18> x) {
+ sc_uint<18> m, y, b;
+ sc_int<18> t;
+
+ y = 0;
+ for( m = 0x10000; m != 0; m >>= 2){
+ b = y | m;
+ y = y >> 1;
+ t = (sc_int<18>)(x | ~(x - b)) >> 16;
+ x = x - (b & t);
+ y = y | (m & t);
+ }
+ return y;
+}
+
+struct stimuli {
+ unsigned it;
+ unsigned is;
+} S[] = {
+{1,1}, {332,18}, {663,25}, {994,31}, {1325,36}, {1656,40}, {1987,44}, {2318,48},
+{2649,51}, {2980,54}, {3311,57}, {3642,60}, {3973,63}, {4304,65}, {4635,68}, {4966,70},
+{5297,72}, {5628,75}, {5959,77}, {6290,79}, {6621,81}, {6952,83}, {7283,85}, {7614,87},
+{7945,89}, {8276,90}, {8607,92}, {8938,94}, {9269,96}, {9600,97}, {9931,99}, {10262,101},
+{10593,102}, {10924,104}, {11255,106}, {11586,107}, {11917,109}, {12248,110}, {12579,112},
+{12910,113}, {13241,115}, {13572,116}, {13903,117}, {14234,119}, {14565,120}, {14896,122},
+{15227,123}, {15558,124}, {15889,126}, {16220,127}, {16551,128}, {16882,129}, {17213,131},
+{17544,132}, {17875,133}, {18206,134}, {18537,136}, {18868,137}, {19199,138}, {19530,139},
+{19861,140}, {20192,142}, {20523,143}, {20854,144}, {21185,145}, {21516,146}, {21847,147},
+{22178,148}, {22509,150}, {22840,151}, {23171,152}, {23502,153}, {23833,154}, {24164,155},
+{24495,156}, {24826,157}, {25157,158}, {25488,159}, {25819,160}, {26150,161}, {26481,162},
+{26812,163}, {27143,164}, {27474,165}, {27805,166}, {28136,167}, {28467,168}, {28798,169},
+{29129,170}, {29460,171}, {29791,172}, {30122,173}, {30453,174}, {30784,175}, {31115,176},
+{31446,177}, {31777,178}, {32108,179}, {32439,180}, {32770,181}, {33101,181}, {33432,182},
+{33763,183}, {34094,184}, {34425,185}, {34756,186}, {35087,187}, {35418,188}, {35749,189},
+{36080,189}, {36411,190}, {36742,191}, {37073,192}, {37404,193}, {37735,194}, {38066,195},
+{38397,195}, {38728,196}, {39059,197}, {39390,198}, {39721,199}, {40052,200}, {40383,200},
+{40714,201}, {41045,202}, {41376,203}, {41707,204}, {42038,205}, {42369,205}, {42700,206},
+{43031,207}, {43362,208}, {43693,209}, {44024,209}, {44355,210}, {44686,211}, {45017,212},
+{45348,212}, {45679,213}, {46010,214}, {46341,215}, {46672,216}, {47003,216}, {47334,217},
+{47665,218}, {47996,219}, {48327,219}, {48658,220}, {48989,221}, {49320,222}, {49651,222},
+{49982,223}, {50313,224}, {50644,225}, {50975,225}, {51306,226}, {51637,227}, {51968,227},
+{52299,228}, {52630,229}, {52961,230}, {53292,230}, {53623,231}, {53954,232}, {54285,232},
+{54616,233}, {54947,234}, {55278,235}, {55609,235}, {55940,236}, {56271,237}, {56602,237},
+{56933,238}, {57264,239}, {57595,239}, {57926,240}, {58257,241}, {58588,242}, {58919,242},
+{59250,243}, {59581,244}, {59912,244}, {60243,245}, {60574,246}, {60905,246}, {61236,247},
+{61567,248}, {61898,248}, {62229,249}, {62560,250}, {62891,250}, {63222,251}, {63553,252},
+{63884,252}, {64215,253}, {64546,254}, {64877,254}, {65208,255}, {65539,256}, {65870,256},
+{66201,257}, {66532,257}, {66863,258}, {67194,259}, {67525,259}, {67856,260}, {68187,261},
+{68518,261}, {68849,262}, {69180,263}, {69511,263}, {69842,264}, {70173,264}, {70504,265},
+{70835,266}, {71166,266}, {71497,267}, {71828,268}, {72159,268}, {72490,269}, {72821,269},
+{73152,270}, {73483,271}, {73814,271}, {74145,272}, {74476,272}, {74807,273}, {75138,274},
+{75469,274}, {75800,275}, {76131,275}, {76462,276}, {76793,277}, {77124,277}, {77455,278},
+{77786,278}, {78117,279}, {78448,280}, {78779,280}, {79110,281}, {79441,281}, {79772,282},
+{80103,283}, {80434,283}, {80765,284}, {81096,284}, {81427,285}, {81758,285}, {82089,286},
+{82420,287}, {82751,287}, {83082,288}, {83413,288}, {83744,289}, {84075,289}, {84406,290},
+{84737,291}, {85068,291}, {85399,292}, {85730,292}, {86061,293}, {86392,293}, {86723,294},
+{87054,295}, {87385,295}, {87716,296}, {88047,296}, {88378,297}, {88709,297}, {89040,298},
+{89371,298}, {89702,299}, {90033,300}, {90364,300}, {90695,301}, {91026,301}, {91357,302},
+{91688,302}, {92019,303}, {92350,303}, {92681,304}, {93012,304}, {93343,305}, {93674,306},
+{94005,306}, {94336,307}, {94667,307}, {94998,308}, {95329,308}, {95660,309}, {95991,309},
+{96322,310}, {96653,310}, {96984,311}, {97315,311}, {97646,312}, {97977,313}, {98308,313},
+{98639,314}, {98970,314}, {99301,315}, {99632,315}, {99963,316}, {100294,316}, {100625,317},
+{100956,317}, {101287,318}, {101618,318}, {101949,319}, {102280,319}, {102611,320}, {102942,320},
+{103273,321}, {103604,321}, {103935,322}, {104266,322}, {104597,323}, {104928,323}, {105259,324},
+{105590,324}, {105921,325}, {106252,325}, {106583,326}, {106914,326}, {107245,327}, {107576,327},
+{107907,328}, {108238,328}, {108569,329}, {108900,330}, {109231,330}, {109562,331}, {109893,331},
+{110224,332}, {110555,332}, {110886,332}, {111217,333}, {111548,333}, {111879,334}, {112210,334},
+{112541,335}, {112872,335}, {113203,336}, {113534,336}, {113865,337}, {114196,337}, {114527,338},
+{114858,338}, {115189,339}, {115520,339}, {115851,340}, {116182,340}, {116513,341}, {116844,341},
+{117175,342}, {117506,342}, {117837,343}, {118168,343}, {118499,344}, {118830,344}, {119161,345},
+{119492,345}, {119823,346}, {120154,346}, {120485,347}, {120816,347}, {121147,348}, {121478,348},
+{121809,349}, {122140,349}, {122471,349}, {122802,350}, {123133,350}, {123464,351}, {123795,351},
+{124126,352}, {124457,352}, {124788,353}, {125119,353}, {125450,354}, {125781,354}, {126112,355},
+{126443,355}, {126774,356}, {127105,356}, {127436,356}, {127767,357}, {128098,357}, {128429,358},
+{128760,358}, {129091,359}, {129422,359}, {129753,360}, {130084,360}, {130415,361}, {130746,361},
+{131077,362}, {131408,362}, {131739,362}, {132070,363}, {132401,363}, {132732,364}, {133063,364},
+{133394,365}, {133725,365}, {134056,366}, {134387,366}, {134718,367}, {135049,367}, {135380,367},
+{135711,368}, {136042,368}, {136373,369}, {136704,369}, {137035,370}, {137366,370}, {137697,371},
+{138028,371}, {138359,371}, {138690,372}, {139021,372}, {139352,373}, {139683,373}, {140014,374},
+{140345,374}, {140676,375}, {141007,375}, {141338,375}, {141669,376}, {142000,376}, {142331,377},
+{142662,377}, {142993,378}, {143324,378}, {143655,379}, {143986,379}, {144317,379}, {144648,380},
+{144979,380}, {145310,381}, {145641,381}, {145972,382}, {146303,382}, {146634,382}, {146965,383},
+{147296,383}, {147627,384}, {147958,384}, {148289,385}, {148620,385}, {148951,385}, {149282,386},
+{149613,386}, {149944,387}, {150275,387}, {150606,388}, {150937,388}, {151268,388}, {151599,389},
+{151930,389}, {152261,390}, {152592,390}, {152923,391}, {153254,391}, {153585,391}, {153916,392},
+{154247,392}, {154578,393}, {154909,393}, {155240,394}, {155571,394}, {155902,394}, {156233,395},
+{156564,395}, {156895,396}, {157226,396}, {157557,396}, {157888,397}, {158219,397}, {158550,398},
+{158881,398}, {159212,399}, {159543,399}, {159874,399}, {160205,400}, {160536,400}, {160867,401},
+{161198,401}, {161529,401}, {161860,402}, {162191,402}, {162522,403}, {162853,403}, {163184,403},
+{163515,404}, {163846,404}, {164177,405}, {164508,405}, {164839,406}, {165170,406}, {165501,406},
+{165832,407}, {166163,407}, {166494,408}, {166825,408}, {167156,408}, {167487,409}, {167818,409},
+{168149,410}, {168480,410}, {168811,410}, {169142,411}, {169473,411}, {169804,412}, {170135,412},
+{170466,412}, {170797,413}, {171128,413}, {171459,414}, {171790,414}, {172121,414}, {172452,415},
+{172783,415}, {173114,416}, {173445,416}, {173776,416}, {174107,417}, {174438,417}, {174769,418},
+{175100,418}, {175431,418}, {175762,419}, {176093,419}, {176424,420}, {176755,420}, {177086,420},
+{177417,421}, {177748,421}, {178079,421}, {178410,422}, {178741,422}, {179072,423}, {179403,423},
+{179734,423}, {180065,424}, {180396,424}, {180727,425}, {181058,425}, {181389,425}, {181720,426},
+{182051,426}, {182382,427}, {182713,427}, {183044,427}, {183375,428}, {183706,428}, {184037,428},
+{184368,429}, {184699,429}, {185030,430}, {185361,430}, {185692,430}, {186023,431}, {186354,431},
+{186685,432}, {187016,432}, {187347,432}, {187678,433}, {188009,433}, {188340,433}, {188671,434},
+{189002,434}, {189333,435}, {189664,435}, {189995,435}, {190326,436}, {190657,436}, {190988,437},
+{191319,437}, {191650,437}, {191981,438}, {192312,438}, {192643,438}, {192974,439}, {193305,439},
+{193636,440}, {193967,440}, {194298,440}, {194629,441}, {194960,441}, {195291,441}, {195622,442},
+{195953,442}, {196284,443}, {196615,443}, {196946,443}, {197277,444}, {197608,444}, {197939,444},
+{198270,445}, {198601,445}, {198932,446}, {199263,446}, {199594,446}, {199925,447}, {200256,447},
+{200587,447}, {200918,448}, {201249,448}, {201580,448}, {201911,449}, {202242,449}, {202573,450},
+{202904,450}, {203235,450}, {203566,451}, {203897,451}, {204228,451}, {204559,452}, {204890,452},
+{205221,453}, {205552,453}, {205883,453}, {206214,454}, {206545,454}, {206876,454}, {207207,455},
+{207538,455}, {207869,455}, {208200,456}, {208531,456}, {208862,457}, {209193,457}, {209524,457},
+{209855,458}, {210186,458}, {210517,458}, {210848,459}, {211179,459}, {211510,459}, {211841,460},
+{212172,460}, {212503,460}, {212834,461}, {213165,461}, {213496,462}, {213827,462}, {214158,462},
+{214489,463}, {214820,463}, {215151,463}, {215482,464}, {215813,464}, {216144,464}, {216475,465},
+{216806,465}, {217137,465}, {217468,466}, {217799,466}, {218130,467}, {218461,467}, {218792,467},
+{219123,468}, {219454,468}, {219785,468}, {220116,469}, {220447,469}, {220778,469}, {221109,470},
+{221440,470}, {221771,470}, {222102,471}, {222433,471}, {222764,471}, {223095,472}, {223426,472},
+{223757,473}, {224088,473}, {224419,473}, {224750,474}, {225081,474}, {225412,474}, {225743,475},
+{226074,475}, {226405,475}, {226736,476}, {227067,476}, {227398,476}, {227729,477}, {228060,477},
+{228391,477}, {228722,478}, {229053,478}, {229384,478}, {229715,479}, {230046,479}, {230377,479},
+{230708,480}, {231039,480}, {231370,481}, {231701,481}, {232032,481}, {232363,482}, {232694,482},
+{233025,482}, {233356,483}, {233687,483}, {234018,483}, {234349,484}, {234680,484}, {235011,484},
+{235342,485}, {235673,485}, {236004,485}, {236335,486}, {236666,486}, {236997,486}, {237328,487},
+{237659,487}, {237990,487}, {238321,488}, {238652,488}, {238983,488}, {239314,489}, {239645,489},
+{239976,489}, {240307,490}, {240638,490}, {240969,490}, {241300,491}, {241631,491}, {241962,491},
+{242293,492}, {242624,492}, {242955,492}, {243286,493}, {243617,493}, {243948,493}, {244279,494},
+{244610,494}, {244941,494}, {245272,495}, {245603,495}, {245934,495}, {246265,496}, {246596,496},
+{246927,496}, {247258,497}, {247589,497}, {247920,497}, {248251,498}, {248582,498}, {248913,498},
+{249244,499}, {249575,499}, {249906,499}, {250237,500}, {250568,500}, {250899,500}, {251230,501},
+{251561,501}, {251892,501}, {252223,502}, {252554,502}, {252885,502}, {253216,503}, {253547,503},
+{253878,503}, {254209,504}, {254540,504}, {254871,504}, {255202,505}, {255533,505}, {255864,505},
+{256195,506}, {256526,506}, {256857,506}, {257188,507}, {257519,507}, {257850,507}, {258181,508},
+{258512,508}, {258843,508}, {259174,509}, {259505,509}, {259836,509}
+};
+
+int
+sc_main(int argc, char *argv[])
+{
+ sc_clock clk;
+ sc_signal<bool> reset;
+ sc_signal<bool> in_rdy;
+ sc_signal<bool> in_vld;
+ sc_signal<bool> out_vld;
+ sc_signal<bool> out_rdy;
+ sc_signal<sc_uint<18> > it;
+ sc_signal<sc_uint<10> > is;
+ int errors;
+ isq *isqp;
+
+ isqp = new isq("isq0");
+ (*isqp)(reset, clk,
+ in_rdy, in_vld, it,
+ out_rdy, out_vld, is);
+
+ reset = 0;
+ sc_start(2, SC_NS);
+ reset = 1;
+ sc_start(2, SC_NS);
+ out_rdy = 1;
+
+ sc_start(1, SC_NS);
+ errors = 0;
+ for(int i = 0; i < sizeof S/sizeof(struct stimuli); i++){
+ while( !in_rdy)
+ sc_start(1, SC_NS);
+
+ in_vld = 1;
+ it.write(S[i].it);
+ do { sc_start(1, SC_NS); in_vld = 0; } while(!out_vld);
+
+ if( is.read() != S[i].is){
+ printf("error it:%d expected is:%d received is:%d\n",
+ (int)S[i].it, (int)S[i].is,
+ (int)is.read());
+ errors++;
+ }
+ }
+
+ if( errors)
+ cout << "Program completed with " << errors << " errors" << endl;
+ else
+ cout << "Program completed." << endl;
+
+ return(0);
+
+}
+
+
+
diff --git a/src/systemc/tests/systemc/examples/trie/golden/trie.log b/src/systemc/tests/systemc/examples/trie/golden/trie.log
new file mode 100644
index 000000000..f0fa7a911
--- /dev/null
+++ b/src/systemc/tests/systemc/examples/trie/golden/trie.log
@@ -0,0 +1,2 @@
+SystemC Simulation
+program complete
diff --git a/src/systemc/tests/systemc/examples/trie/trie.cpp b/src/systemc/tests/systemc/examples/trie/trie.cpp
new file mode 100644
index 000000000..7714ce657
--- /dev/null
+++ b/src/systemc/tests/systemc/examples/trie/trie.cpp
@@ -0,0 +1,308 @@
+#include <stdio.h>
+#include "systemc.h"
+
+SC_MODULE(lc)
+{
+ sc_out<bool> DIN_rdy;
+ sc_in<bool> DIN_vld;
+#define LOAD_ADDR 0
+#define LOAD_DATA 1
+#define LOOKUP 2 // really op(1) == 1 and op(0) - don't care
+ sc_in<sc_uint<2> > DIN_op;
+ sc_in<sc_uint<32> > DIN_data_in;
+ sc_in<bool> DOUT_rdy;
+ sc_out<bool> DOUT_vld;
+ sc_out<sc_uint<32> > DOUT_hop;
+ sc_in<bool> RSTN;
+ sc_in_clk CLK;
+
+ void thread();
+ sc_uint<20> extract(sc_uint<32>, sc_uint<7>, sc_uint<5>);
+ sc_uint<10> lookup(sc_uint<32>);
+
+ sc_uint<32> M[1024];
+ sc_uint<32> addr; // latched addr for loading memory
+
+ SC_CTOR(lc){
+ SC_CTHREAD(thread, CLK.pos());
+ reset_signal_is(RSTN,false);
+ }
+};
+
+//
+// this implements the level-compressed trie
+// ip routing algorithm that is proposed in:
+//
+// "Fast Address Lookup for Internet Routers"
+// Stefan Nilsson and Gunnar Karlsson
+// Proc IFIP 4th International Conference on BroadBand Communication
+// pp. 11-22, 1998
+//
+//
+void
+lc::thread()
+{
+ if( !RSTN){
+ DIN_rdy = 1;
+ DOUT_vld = 0;
+ wait(1);
+ }
+
+ for(;;){
+ bool tmp_vld;
+ bool tmp_rdy;
+ sc_uint<2> op;
+ sc_uint<32> data_in;
+ sc_uint<32> hop;
+
+ {
+ do {
+ tmp_vld = DIN_vld.read();
+ op = DIN_op.read();
+ data_in = DIN_data_in.read();
+ wait(1);
+ } while( !tmp_vld);
+ }
+
+ if( op == 0){
+ // latch address
+ addr = data_in;
+ wait(1);
+ } else if(op == 1){
+ // load memory
+ M[addr] = data_in;
+ wait(1);
+ } else if( op[1] == 1){
+ // do the ip lookup to next hop
+ hop = lookup(data_in);
+ {
+ DIN_rdy = 0;
+ do {
+ tmp_rdy = DOUT_rdy.read();
+ wait(1);
+ } while( !tmp_rdy);
+ DOUT_vld = 1;
+ DOUT_hop.write(hop);
+ DIN_rdy = 1;
+ wait(1);
+ DOUT_vld = 0;
+ }
+ }
+ }
+
+}
+
+sc_uint<20>
+lc::extract(sc_uint<32> x, sc_uint<7> p, sc_uint<5> w)
+{
+ return( (x>>(p-w+1)) & ~(~0<<w) );
+}
+
+#define BRANCH(T) T.range(31,27)
+#define SKIP(T) T.range(26,20)
+#define ADDR(T) T.range(19,0)
+#define LEN(T) T.range(31,25)
+#define NEXT_HOP(T) T.range(24,15)
+#define NEXT_PREFIX(T) T.range(14,0)
+
+sc_uint<10>
+lc::lookup(sc_uint<32> ip)
+{
+ sc_uint<7> pos;
+ sc_uint<5> branch;
+ sc_uint<20> addr;
+ sc_uint<32> t;
+ sc_uint<32> ip_prefix;
+ sc_uint<10> next_hop;
+ sc_uint<32> mask;
+
+ t = M[0];
+ pos = SKIP(t);
+ branch = BRANCH(t);
+ addr = ADDR(t);
+ while(branch != 0){
+ addr = addr + extract(ip, pos, branch);
+ t = M[addr];
+ pos = pos - (branch + SKIP(t));
+ branch = BRANCH(t);
+ addr = ADDR(t);
+ }
+
+
+ next_hop = 0;
+ for(;;) {
+ addr <<= 1;
+
+ ip_prefix = M[addr];
+ t = M[addr|1];
+ mask = ~0 << (32-LEN(t));
+ if( (ip_prefix&mask) == (ip&mask)){
+ next_hop = NEXT_HOP(t);
+ break;
+ }
+ addr = NEXT_PREFIX(t);
+ if( addr == 0)
+ break;
+ }
+
+ return(next_hop);
+}
+
+
+/*
+ * hop prefix(bits 31 .. 0)
+ * 1 0000*
+ * 2 0001*
+ * 3 00101*
+ * 4 010*
+ * 5 0110*
+ * 6 0111*
+ * 7 100*
+ * 8 101000*
+ * 9 101001*
+ * 10 10101*
+ * 11 10110*
+ * 12 10111*
+ * 13 110*
+ * 14 11101000*
+ * 15 11101001*
+ *
+ * "not in table" produces a hop of 0
+ */
+
+#define TRIE(LN, SK, AD) \
+ ((((LN)&0x1f)<<27) | (((SK)&0x7f)<<20) | ((AD)&0xfffff))
+#define E(LN, NHP, NPX) \
+ ((((LN)&0x7f)<<25) | (((NHP)&0x3ff)<<15) | ((((NPX))&0x7fff)))
+
+
+#define M_SIZE 52
+sc_uint<32> M[M_SIZE] = {
+/* TRIE */
+/* 00 */ TRIE(3, 31, 1),
+/* 01 */ TRIE(1, 0, 9),
+/* 02 */ TRIE(0, 2, 2+11),
+/* 03 */ TRIE(0, 0, 3+11),
+/* 04 */ TRIE(1, 0, 11),
+/* 05 */ TRIE(0, 0, 6+11),
+/* 06 */ TRIE(2, 0, 13),
+/* 07 */ TRIE(0, 0, 12+11),
+/* 08 */ TRIE(1, 4, 17),
+/* 09 */ TRIE(0, 0, 0+11),
+/* 10 */ TRIE(0, 0, 1+11),
+/* 11 */ TRIE(0, 0, 4+11),
+/* 12 */ TRIE(0, 0, 5+11),
+/* 13 */ TRIE(1, 0, 19),
+/* 14 */ TRIE(0, 0, 9+11),
+/* 15 */ TRIE(0, 0, 10+11),
+/* 16 */ TRIE(0, 0, 11+11),
+/* 17 */ TRIE(0, 0, 13+11),
+/* 18 */ TRIE(0, 0, 14+11),
+/* 19 */ TRIE(0, 0, 7+11),
+/* 20 */ TRIE(0, 0, 8+11),
+/* 21 */ 0, /* pad */
+/* BASE + PREFIX */
+/* 22 */ 0x00000000, E(4, 1, 0),
+/* 24 */ 0x10000000, E(4, 2, 0),
+/* 26 */ 0x28000000, E(5, 3, 0),
+/* 28 */ 0x40000000, E(3, 4, 0),
+/* 31 */ 0x60000000, E(4, 5, 0),
+/* 32 */ 0x70000000, E(4, 6, 0),
+/* 34 */ 0x80000000, E(3, 7, 0),
+/* 36 */ 0xa0000000, E(6, 8, 0),
+/* 38 */ 0xa4000000, E(6, 9, 0),
+/* 40 */ 0xa8000000, E(5, 10, 0),
+/* 42 */ 0xb0000000, E(5, 11, 0),
+/* 44 */ 0xb8000000, E(5, 12, 0),
+/* 46 */ 0xc0000000, E(3, 13, 0),
+/* 48 */ 0xe8000000, E(8, 14, 0),
+/* 50 */ 0xe9000000, E(8, 15, 0)
+};
+
+
+struct stimuli {
+ unsigned int ip;
+ int hop;
+} S[] = {
+ { 0xf0000000, 0 },
+ { 0x10000000, 2 },
+ { 0x7c000000, 6 },
+ { 0x7c001000, 6 },
+ { 0x7c000070, 6 },
+};
+
+int
+sc_main(int argc, char *argv[])
+{
+ sc_clock clk;
+ sc_signal<bool> reset;
+ sc_signal<bool> in_rdy;
+ sc_signal<bool> in_vld;
+ sc_signal<bool> out_vld;
+ sc_signal<bool> out_rdy;
+ sc_signal<sc_uint<2> > op;
+ sc_signal<sc_uint<32> > data;
+ sc_signal<sc_uint<32> > hop;
+ int i;
+ int m_addr;
+ lc *lcp;
+
+ lcp = new lc("lc0");
+ (*lcp)(in_rdy, in_vld,
+ op, data,
+ out_rdy, out_vld,
+ hop,
+ reset, clk);
+
+ reset = 0;
+ sc_start(2, SC_NS);
+ reset = 1;
+ sc_start(2, SC_NS);
+ out_rdy = 1;
+
+ /*
+ * download the RAM containing
+ * the routing data
+ */
+ for(i = 0, m_addr = 0; i < M_SIZE; i++, m_addr++){
+ while(!in_rdy) sc_start(1, SC_NS);
+ in_vld = 1;
+ op.write(LOAD_ADDR);
+ data.write(m_addr);
+ do { sc_start(1, SC_NS); in_vld = 0; } while(!in_rdy);
+ sc_start(1, SC_NS);
+ in_vld = 1;
+ op.write(LOAD_DATA);
+ data.write(M[m_addr]);
+ do { sc_start(1, SC_NS); in_vld = 0; } while(!in_rdy);
+ sc_start(1, SC_NS);
+ }
+
+ /*
+ * apply some ip's and see what
+ * comes back as next-hops
+ */
+ for(i = 0; i < sizeof S/sizeof(struct stimuli); i++){
+ while(!in_rdy) sc_start(1, SC_NS);
+ in_vld = 1;
+ op.write(LOOKUP);
+ data.write(S[i].ip);
+ do { sc_start(1, SC_NS); in_vld = 0; } while(!out_vld);
+ unsigned int h = hop.read();
+ if( h != S[i].hop){
+ cout << S[i].ip << " should be hop " << S[i].hop
+ << " got hop " << h << endl;
+ }
+ }
+ cout << "program complete" << endl;
+ return 0;
+
+}
+
+
+
+
+
+
+
+
diff --git a/src/systemc/tests/systemc/examples/updown/golden/updown.log b/src/systemc/tests/systemc/examples/updown/golden/updown.log
new file mode 100644
index 000000000..983d78412
--- /dev/null
+++ b/src/systemc/tests/systemc/examples/updown/golden/updown.log
@@ -0,0 +1,20 @@
+SystemC Simulation
+clock up down data_in parity_out carry_out borrow_out count_out
+ 1 0 0 200 1 0 0 200
+ 2 1 0 0 1 0 0 203
+ 3 1 0 0 1 0 0 206
+ 4 0 1 0 0 0 0 201
+ 5 0 1 0 1 0 0 196
+ 6 0 1 0 1 0 0 191
+ 7 1 1 0 1 0 0 191
+ 8 1 1 0 1 0 0 191
+ 9 1 1 0 1 0 0 191
+ 10 0 0 200 1 0 0 200
+ 11 1 1 0 1 0 0 200
+ 12 1 1 0 1 0 0 200
+ 13 0 1 0 0 0 0 195
+ 14 0 0 2 1 0 0 2
+ 15 0 1 0 0 0 1 509
+ 16 0 0 511 1 0 0 511
+ 17 1 0 0 1 1 0 2
+ 17 1 0 0 1 1 0 2
diff --git a/src/systemc/tests/systemc/examples/updown/updown.cpp b/src/systemc/tests/systemc/examples/updown/updown.cpp
new file mode 100644
index 000000000..f6c6046cb
--- /dev/null
+++ b/src/systemc/tests/systemc/examples/updown/updown.cpp
@@ -0,0 +1,134 @@
+#include "systemc.h"
+#include "specialized_signals/scx_signal_int.h"
+#include "specialized_signals/scx_signal_signed.h"
+#include "specialized_signals/scx_signal_uint.h"
+#include "specialized_signals/scx_signal_unsigned.h"
+
+SC_MODULE(up_down)
+{
+ sc_in_clk clk;
+ sc_in<sc_uint<1> > up;
+ sc_in<sc_uint<1> > down;
+ sc_in<sc_uint<9> > data_in;
+ sc_inout<sc_uint<1> > parity_out;
+ sc_inout<sc_uint<1> > carry_out;
+ sc_inout<sc_uint<1> > borrow_out;
+ sc_inout<sc_uint<9> > count_out;
+
+ sc_uint<10> cnt_dn;
+ sc_uint<10> cnt_up;
+ sc_uint<9> count_nxt;
+ sc_uint<1> load;
+
+ SC_CTOR(up_down)
+ {
+ SC_METHOD(run);
+ sensitive << clk.pos();
+ }
+
+ void run()
+ {
+ cnt_dn = count_out - 5;
+ cnt_up = count_out + 3;
+
+ load = 1;
+ switch( (unsigned int )(up,down) ) {
+ case(0):
+ count_nxt = data_in;
+ break;
+ case(1):
+ count_nxt = cnt_dn;
+ break;
+ case(2):
+ count_nxt = cnt_up;
+ break;
+ case(3):
+ load = 0;
+ break;
+ }
+
+ if( load) {
+ parity_out = count_nxt.xor_reduce();
+ carry_out = up&cnt_up[9];
+ borrow_out = down&cnt_dn[9];
+ count_out = count_nxt;
+ }
+ }
+};
+
+
+#define UP_DOWN(up, down) up, down
+
+struct stimulus {
+ int up;
+ int down;
+ int data_in;
+} s[] = {
+ { UP_DOWN(0, 0), 200 }, /* load 200 */
+ { UP_DOWN(1, 0), 0 }, /* inc */
+ { UP_DOWN(1, 0), 0 }, /* inc */
+ { UP_DOWN(0, 1), 0 }, /* dec */
+ { UP_DOWN(0, 1), 0 }, /* dec */
+ { UP_DOWN(0, 1), 0 }, /* dec */
+ { UP_DOWN(1, 1), 0 }, /* hold */
+ { UP_DOWN(1, 1), 0 }, /* hold */
+ { UP_DOWN(1, 1), 0 }, /* hold */
+ { UP_DOWN(0, 0), 200 }, /* load 200 */
+ { UP_DOWN(1, 1), 0 }, /* hold */
+ { UP_DOWN(1, 1), 0 }, /* hold */
+ { UP_DOWN(0, 1), 0 }, /* dec */
+ { UP_DOWN(0, 0), 2 }, /* load 2 */
+ { UP_DOWN(0, 1), 0 }, /* dec */
+ { UP_DOWN(0, 0), 0x1ff},/* load 0x1ff */
+ { UP_DOWN(1, 0), 0 }, /* inc */
+};
+
+
+int sc_main(int argc, char* argv[])
+{
+ sc_signal<sc_uint<1> > borrow_out;
+ sc_signal<sc_uint<1> > carry_out;
+ sc_clock clock;
+ sc_signal<sc_uint<9> > count_out;
+ sc_signal<sc_uint<9> > data_in;
+ sc_signal<sc_uint<1> > down;
+ unsigned int i;
+ sc_signal<sc_uint<1> > parity_out;
+ sc_signal<sc_uint<1> > up;
+
+ up_down up_down_0("up_down_0");
+ up_down_0.borrow_out(borrow_out);
+ up_down_0.carry_out(carry_out);
+ up_down_0.data_in(data_in);
+ up_down_0.clk(clock);
+ up_down_0.count_out(count_out);
+ up_down_0.down(down);
+ up_down_0.parity_out(parity_out);
+ up_down_0.up(up);
+
+ printf("%5s %2s %4s %7s %10s %8s %10s %9s\n",
+ "clock", "up", "down", "data_in", "parity_out",
+ "carry_out", "borrow_out", "count_out");
+
+ for( i = 0; i < sizeof s/sizeof(struct stimulus); i++) {
+ up = s[i].up;
+ down = s[i].down;
+ data_in = s[i].data_in;
+
+ sc_start(1, SC_NS);
+
+ printf("%5d %2d %4d %7d %10d %8d %10d %9d\n",
+ (int)sc_time_stamp().to_double()/1000, (int)up, (int)down,
+ (int)data_in, (int)parity_out, (int)carry_out, (int)borrow_out,
+ (int)count_out);
+ }
+
+ /* get last register values */
+ printf("%5d %2d %4d %7d %10d %8d %10d %9d\n",
+ (int)sc_time_stamp().to_double()/1000, (int)up, (int)down,
+ (int)data_in, (int)parity_out, (int)carry_out, (int)borrow_out,
+ (int)count_out);
+
+ return 0;
+}
+