112855Sgabeblack@google.com#include <stdio.h> 212855Sgabeblack@google.com#include "systemc.h" 312855Sgabeblack@google.com 412855Sgabeblack@google.comSC_MODULE(lc) 512855Sgabeblack@google.com{ 612855Sgabeblack@google.com sc_out<bool> DIN_rdy; 712855Sgabeblack@google.com sc_in<bool> DIN_vld; 812855Sgabeblack@google.com#define LOAD_ADDR 0 912855Sgabeblack@google.com#define LOAD_DATA 1 1012855Sgabeblack@google.com#define LOOKUP 2 // really op(1) == 1 and op(0) - don't care 1112855Sgabeblack@google.com sc_in<sc_uint<2> > DIN_op; 1212855Sgabeblack@google.com sc_in<sc_uint<32> > DIN_data_in; 1312855Sgabeblack@google.com sc_in<bool> DOUT_rdy; 1412855Sgabeblack@google.com sc_out<bool> DOUT_vld; 1512855Sgabeblack@google.com sc_out<sc_uint<32> > DOUT_hop; 1612855Sgabeblack@google.com sc_in<bool> RSTN; 1712855Sgabeblack@google.com sc_in_clk CLK; 1812855Sgabeblack@google.com 1912855Sgabeblack@google.com void thread(); 2012855Sgabeblack@google.com sc_uint<20> extract(sc_uint<32>, sc_uint<7>, sc_uint<5>); 2112855Sgabeblack@google.com sc_uint<10> lookup(sc_uint<32>); 2212855Sgabeblack@google.com 2312855Sgabeblack@google.com sc_uint<32> M[1024]; 2412855Sgabeblack@google.com sc_uint<32> addr; // latched addr for loading memory 2512855Sgabeblack@google.com 2612855Sgabeblack@google.com SC_CTOR(lc){ 2712855Sgabeblack@google.com SC_CTHREAD(thread, CLK.pos()); 2812855Sgabeblack@google.com reset_signal_is(RSTN,false); 2912855Sgabeblack@google.com } 3012855Sgabeblack@google.com}; 3112855Sgabeblack@google.com 3212855Sgabeblack@google.com// 3312855Sgabeblack@google.com// this implements the level-compressed trie 3412855Sgabeblack@google.com// ip routing algorithm that is proposed in: 3512855Sgabeblack@google.com// 3612855Sgabeblack@google.com// "Fast Address Lookup for Internet Routers" 3712855Sgabeblack@google.com// Stefan Nilsson and Gunnar Karlsson 3812855Sgabeblack@google.com// Proc IFIP 4th International Conference on BroadBand Communication 3912855Sgabeblack@google.com// pp. 11-22, 1998 4012855Sgabeblack@google.com// 4112855Sgabeblack@google.com// 4212855Sgabeblack@google.comvoid 4312855Sgabeblack@google.comlc::thread() 4412855Sgabeblack@google.com{ 4512855Sgabeblack@google.com if( !RSTN){ 4612855Sgabeblack@google.com DIN_rdy = 1; 4712855Sgabeblack@google.com DOUT_vld = 0; 4812855Sgabeblack@google.com wait(1); 4912855Sgabeblack@google.com } 5012855Sgabeblack@google.com 5112855Sgabeblack@google.com for(;;){ 5212855Sgabeblack@google.com bool tmp_vld; 5312855Sgabeblack@google.com bool tmp_rdy; 5412855Sgabeblack@google.com sc_uint<2> op; 5512855Sgabeblack@google.com sc_uint<32> data_in; 5612855Sgabeblack@google.com sc_uint<32> hop; 5712855Sgabeblack@google.com 5812855Sgabeblack@google.com { 5912855Sgabeblack@google.com do { 6012855Sgabeblack@google.com tmp_vld = DIN_vld.read(); 6112855Sgabeblack@google.com op = DIN_op.read(); 6212855Sgabeblack@google.com data_in = DIN_data_in.read(); 6312855Sgabeblack@google.com wait(1); 6412855Sgabeblack@google.com } while( !tmp_vld); 6512855Sgabeblack@google.com } 6612855Sgabeblack@google.com 6712855Sgabeblack@google.com if( op == 0){ 6812855Sgabeblack@google.com // latch address 6912855Sgabeblack@google.com addr = data_in; 7012855Sgabeblack@google.com wait(1); 7112855Sgabeblack@google.com } else if(op == 1){ 7212855Sgabeblack@google.com // load memory 7312855Sgabeblack@google.com M[addr] = data_in; 7412855Sgabeblack@google.com wait(1); 7512855Sgabeblack@google.com } else if( op[1] == 1){ 7612855Sgabeblack@google.com // do the ip lookup to next hop 7712855Sgabeblack@google.com hop = lookup(data_in); 7812855Sgabeblack@google.com { 7912855Sgabeblack@google.com DIN_rdy = 0; 8012855Sgabeblack@google.com do { 8112855Sgabeblack@google.com tmp_rdy = DOUT_rdy.read(); 8212855Sgabeblack@google.com wait(1); 8312855Sgabeblack@google.com } while( !tmp_rdy); 8412855Sgabeblack@google.com DOUT_vld = 1; 8512855Sgabeblack@google.com DOUT_hop.write(hop); 8612855Sgabeblack@google.com DIN_rdy = 1; 8712855Sgabeblack@google.com wait(1); 8812855Sgabeblack@google.com DOUT_vld = 0; 8912855Sgabeblack@google.com } 9012855Sgabeblack@google.com } 9112855Sgabeblack@google.com } 9212855Sgabeblack@google.com 9312855Sgabeblack@google.com} 9412855Sgabeblack@google.com 9512855Sgabeblack@google.comsc_uint<20> 9612855Sgabeblack@google.comlc::extract(sc_uint<32> x, sc_uint<7> p, sc_uint<5> w) 9712855Sgabeblack@google.com{ 9812855Sgabeblack@google.com return( (x>>(p-w+1)) & ~(~0<<w) ); 9912855Sgabeblack@google.com} 10012855Sgabeblack@google.com 10112855Sgabeblack@google.com#define BRANCH(T) T.range(31,27) 10212855Sgabeblack@google.com#define SKIP(T) T.range(26,20) 10312855Sgabeblack@google.com#define ADDR(T) T.range(19,0) 10412855Sgabeblack@google.com#define LEN(T) T.range(31,25) 10512855Sgabeblack@google.com#define NEXT_HOP(T) T.range(24,15) 10612855Sgabeblack@google.com#define NEXT_PREFIX(T) T.range(14,0) 10712855Sgabeblack@google.com 10812855Sgabeblack@google.comsc_uint<10> 10912855Sgabeblack@google.comlc::lookup(sc_uint<32> ip) 11012855Sgabeblack@google.com{ 11112855Sgabeblack@google.com sc_uint<7> pos; 11212855Sgabeblack@google.com sc_uint<5> branch; 11312855Sgabeblack@google.com sc_uint<20> addr; 11412855Sgabeblack@google.com sc_uint<32> t; 11512855Sgabeblack@google.com sc_uint<32> ip_prefix; 11612855Sgabeblack@google.com sc_uint<10> next_hop; 11712855Sgabeblack@google.com sc_uint<32> mask; 11812855Sgabeblack@google.com 11912855Sgabeblack@google.com t = M[0]; 12012855Sgabeblack@google.com pos = SKIP(t); 12112855Sgabeblack@google.com branch = BRANCH(t); 12212855Sgabeblack@google.com addr = ADDR(t); 12312855Sgabeblack@google.com while(branch != 0){ 12412855Sgabeblack@google.com addr = addr + extract(ip, pos, branch); 12512855Sgabeblack@google.com t = M[addr]; 12612855Sgabeblack@google.com pos = pos - (branch + SKIP(t)); 12712855Sgabeblack@google.com branch = BRANCH(t); 12812855Sgabeblack@google.com addr = ADDR(t); 12912855Sgabeblack@google.com } 13012855Sgabeblack@google.com 13112855Sgabeblack@google.com 13212855Sgabeblack@google.com next_hop = 0; 13312855Sgabeblack@google.com for(;;) { 13412855Sgabeblack@google.com addr <<= 1; 13512855Sgabeblack@google.com 13612855Sgabeblack@google.com ip_prefix = M[addr]; 13712855Sgabeblack@google.com t = M[addr|1]; 13812855Sgabeblack@google.com mask = ~0 << (32-LEN(t)); 13912855Sgabeblack@google.com if( (ip_prefix&mask) == (ip&mask)){ 14012855Sgabeblack@google.com next_hop = NEXT_HOP(t); 14112855Sgabeblack@google.com break; 14212855Sgabeblack@google.com } 14312855Sgabeblack@google.com addr = NEXT_PREFIX(t); 14412855Sgabeblack@google.com if( addr == 0) 14512855Sgabeblack@google.com break; 14612855Sgabeblack@google.com } 14712855Sgabeblack@google.com 14812855Sgabeblack@google.com return(next_hop); 14912855Sgabeblack@google.com} 15012855Sgabeblack@google.com 15112855Sgabeblack@google.com 15212855Sgabeblack@google.com/* 15312855Sgabeblack@google.com * hop prefix(bits 31 .. 0) 15412855Sgabeblack@google.com * 1 0000* 15512855Sgabeblack@google.com * 2 0001* 15612855Sgabeblack@google.com * 3 00101* 15712855Sgabeblack@google.com * 4 010* 15812855Sgabeblack@google.com * 5 0110* 15912855Sgabeblack@google.com * 6 0111* 16012855Sgabeblack@google.com * 7 100* 16112855Sgabeblack@google.com * 8 101000* 16212855Sgabeblack@google.com * 9 101001* 16312855Sgabeblack@google.com * 10 10101* 16412855Sgabeblack@google.com * 11 10110* 16512855Sgabeblack@google.com * 12 10111* 16612855Sgabeblack@google.com * 13 110* 16712855Sgabeblack@google.com * 14 11101000* 16812855Sgabeblack@google.com * 15 11101001* 16912855Sgabeblack@google.com * 17012855Sgabeblack@google.com * "not in table" produces a hop of 0 17112855Sgabeblack@google.com */ 17212855Sgabeblack@google.com 17312855Sgabeblack@google.com#define TRIE(LN, SK, AD) \ 17412855Sgabeblack@google.com ((((LN)&0x1f)<<27) | (((SK)&0x7f)<<20) | ((AD)&0xfffff)) 17512855Sgabeblack@google.com#define E(LN, NHP, NPX) \ 17612855Sgabeblack@google.com ((((LN)&0x7f)<<25) | (((NHP)&0x3ff)<<15) | ((((NPX))&0x7fff))) 17712855Sgabeblack@google.com 17812855Sgabeblack@google.com 17912855Sgabeblack@google.com#define M_SIZE 52 18012855Sgabeblack@google.comsc_uint<32> M[M_SIZE] = { 18112855Sgabeblack@google.com/* TRIE */ 18212855Sgabeblack@google.com/* 00 */ TRIE(3, 31, 1), 18312855Sgabeblack@google.com/* 01 */ TRIE(1, 0, 9), 18412855Sgabeblack@google.com/* 02 */ TRIE(0, 2, 2+11), 18512855Sgabeblack@google.com/* 03 */ TRIE(0, 0, 3+11), 18612855Sgabeblack@google.com/* 04 */ TRIE(1, 0, 11), 18712855Sgabeblack@google.com/* 05 */ TRIE(0, 0, 6+11), 18812855Sgabeblack@google.com/* 06 */ TRIE(2, 0, 13), 18912855Sgabeblack@google.com/* 07 */ TRIE(0, 0, 12+11), 19012855Sgabeblack@google.com/* 08 */ TRIE(1, 4, 17), 19112855Sgabeblack@google.com/* 09 */ TRIE(0, 0, 0+11), 19212855Sgabeblack@google.com/* 10 */ TRIE(0, 0, 1+11), 19312855Sgabeblack@google.com/* 11 */ TRIE(0, 0, 4+11), 19412855Sgabeblack@google.com/* 12 */ TRIE(0, 0, 5+11), 19512855Sgabeblack@google.com/* 13 */ TRIE(1, 0, 19), 19612855Sgabeblack@google.com/* 14 */ TRIE(0, 0, 9+11), 19712855Sgabeblack@google.com/* 15 */ TRIE(0, 0, 10+11), 19812855Sgabeblack@google.com/* 16 */ TRIE(0, 0, 11+11), 19912855Sgabeblack@google.com/* 17 */ TRIE(0, 0, 13+11), 20012855Sgabeblack@google.com/* 18 */ TRIE(0, 0, 14+11), 20112855Sgabeblack@google.com/* 19 */ TRIE(0, 0, 7+11), 20212855Sgabeblack@google.com/* 20 */ TRIE(0, 0, 8+11), 20312855Sgabeblack@google.com/* 21 */ 0, /* pad */ 20412855Sgabeblack@google.com/* BASE + PREFIX */ 20512855Sgabeblack@google.com/* 22 */ 0x00000000, E(4, 1, 0), 20612855Sgabeblack@google.com/* 24 */ 0x10000000, E(4, 2, 0), 20712855Sgabeblack@google.com/* 26 */ 0x28000000, E(5, 3, 0), 20812855Sgabeblack@google.com/* 28 */ 0x40000000, E(3, 4, 0), 20912855Sgabeblack@google.com/* 31 */ 0x60000000, E(4, 5, 0), 21012855Sgabeblack@google.com/* 32 */ 0x70000000, E(4, 6, 0), 21112855Sgabeblack@google.com/* 34 */ 0x80000000, E(3, 7, 0), 21212855Sgabeblack@google.com/* 36 */ 0xa0000000, E(6, 8, 0), 21312855Sgabeblack@google.com/* 38 */ 0xa4000000, E(6, 9, 0), 21412855Sgabeblack@google.com/* 40 */ 0xa8000000, E(5, 10, 0), 21512855Sgabeblack@google.com/* 42 */ 0xb0000000, E(5, 11, 0), 21612855Sgabeblack@google.com/* 44 */ 0xb8000000, E(5, 12, 0), 21712855Sgabeblack@google.com/* 46 */ 0xc0000000, E(3, 13, 0), 21812855Sgabeblack@google.com/* 48 */ 0xe8000000, E(8, 14, 0), 21912855Sgabeblack@google.com/* 50 */ 0xe9000000, E(8, 15, 0) 22012855Sgabeblack@google.com}; 22112855Sgabeblack@google.com 22212855Sgabeblack@google.com 22312855Sgabeblack@google.comstruct stimuli { 22412855Sgabeblack@google.com unsigned int ip; 22512855Sgabeblack@google.com int hop; 22612855Sgabeblack@google.com} S[] = { 22712855Sgabeblack@google.com { 0xf0000000, 0 }, 22812855Sgabeblack@google.com { 0x10000000, 2 }, 22912855Sgabeblack@google.com { 0x7c000000, 6 }, 23012855Sgabeblack@google.com { 0x7c001000, 6 }, 23112855Sgabeblack@google.com { 0x7c000070, 6 }, 23212855Sgabeblack@google.com}; 23312855Sgabeblack@google.com 23412855Sgabeblack@google.comint 23512855Sgabeblack@google.comsc_main(int argc, char *argv[]) 23612855Sgabeblack@google.com{ 23712855Sgabeblack@google.com sc_clock clk; 23812855Sgabeblack@google.com sc_signal<bool> reset; 23912855Sgabeblack@google.com sc_signal<bool> in_rdy; 24012855Sgabeblack@google.com sc_signal<bool> in_vld; 24112855Sgabeblack@google.com sc_signal<bool> out_vld; 24212855Sgabeblack@google.com sc_signal<bool> out_rdy; 24312855Sgabeblack@google.com sc_signal<sc_uint<2> > op; 24412855Sgabeblack@google.com sc_signal<sc_uint<32> > data; 24512855Sgabeblack@google.com sc_signal<sc_uint<32> > hop; 24612855Sgabeblack@google.com int i; 24712855Sgabeblack@google.com int m_addr; 24812855Sgabeblack@google.com lc *lcp; 24912855Sgabeblack@google.com 25012855Sgabeblack@google.com lcp = new lc("lc0"); 25112855Sgabeblack@google.com (*lcp)(in_rdy, in_vld, 25212855Sgabeblack@google.com op, data, 25312855Sgabeblack@google.com out_rdy, out_vld, 25412855Sgabeblack@google.com hop, 25512855Sgabeblack@google.com reset, clk); 25612855Sgabeblack@google.com 25712855Sgabeblack@google.com reset = 0; 25812855Sgabeblack@google.com sc_start(2, SC_NS); 25912855Sgabeblack@google.com reset = 1; 26012855Sgabeblack@google.com sc_start(2, SC_NS); 26112855Sgabeblack@google.com out_rdy = 1; 26212855Sgabeblack@google.com 26312855Sgabeblack@google.com /* 26412855Sgabeblack@google.com * download the RAM containing 26512855Sgabeblack@google.com * the routing data 26612855Sgabeblack@google.com */ 26712855Sgabeblack@google.com for(i = 0, m_addr = 0; i < M_SIZE; i++, m_addr++){ 26812855Sgabeblack@google.com while(!in_rdy) sc_start(1, SC_NS); 26912855Sgabeblack@google.com in_vld = 1; 27012855Sgabeblack@google.com op.write(LOAD_ADDR); 27112855Sgabeblack@google.com data.write(m_addr); 27212855Sgabeblack@google.com do { sc_start(1, SC_NS); in_vld = 0; } while(!in_rdy); 27312855Sgabeblack@google.com sc_start(1, SC_NS); 27412855Sgabeblack@google.com in_vld = 1; 27512855Sgabeblack@google.com op.write(LOAD_DATA); 27612855Sgabeblack@google.com data.write(M[m_addr]); 27712855Sgabeblack@google.com do { sc_start(1, SC_NS); in_vld = 0; } while(!in_rdy); 27812855Sgabeblack@google.com sc_start(1, SC_NS); 27912855Sgabeblack@google.com } 28012855Sgabeblack@google.com 28112855Sgabeblack@google.com /* 28212855Sgabeblack@google.com * apply some ip's and see what 28312855Sgabeblack@google.com * comes back as next-hops 28412855Sgabeblack@google.com */ 28512855Sgabeblack@google.com for(i = 0; i < sizeof S/sizeof(struct stimuli); i++){ 28612855Sgabeblack@google.com while(!in_rdy) sc_start(1, SC_NS); 28712855Sgabeblack@google.com in_vld = 1; 28812855Sgabeblack@google.com op.write(LOOKUP); 28912855Sgabeblack@google.com data.write(S[i].ip); 29012855Sgabeblack@google.com do { sc_start(1, SC_NS); in_vld = 0; } while(!out_vld); 29112855Sgabeblack@google.com unsigned int h = hop.read(); 29212855Sgabeblack@google.com if( h != S[i].hop){ 29312855Sgabeblack@google.com cout << S[i].ip << " should be hop " << S[i].hop 29412855Sgabeblack@google.com << " got hop " << h << endl; 29512855Sgabeblack@google.com } 29612855Sgabeblack@google.com } 29712855Sgabeblack@google.com cout << "program complete" << endl; 29812855Sgabeblack@google.com return 0; 29912855Sgabeblack@google.com 30012855Sgabeblack@google.com} 30112855Sgabeblack@google.com 30212855Sgabeblack@google.com 30312855Sgabeblack@google.com 30412855Sgabeblack@google.com 30512855Sgabeblack@google.com 30612855Sgabeblack@google.com 30712855Sgabeblack@google.com 30812855Sgabeblack@google.com 309