-- -*- Mode: LUA; tab-width: 2 -*-

PCR_template = reg {
	 name = "Port Control Register";
	 description = "Register controlling the mode of certain RTU port.";
	 prefix = "PCR";

	 field {
			name = "Learning enable";
			description = "1: enables learning process on this port. Unrecognized requests will be put into UFIFO\
			               0: disables learning. Unrecognized requests will be either broadcast or dropped.";
			prefix = "LEARN_EN";
			
			type = BIT;
			access_dev = READ_ONLY;
			access_bus = READ_WRITE;
	 };
	 
	 field {
			name = "Pass all packets";
			description = "1: all packets are passed (depending on the rules in RT table). \
			               0: all packets are dropped on this port.";

			prefix = "PASS_ALL";
			
			type = BIT;
			access_dev = READ_ONLY;
			access_bus = READ_WRITE;
	 };

	 field {
			name = "Pass BPDUs";
			description = "1: BPDU packets (with dst MAC 01:80:c2:00:00:00) are passed according to RT rules. This setting overrides PASS_ALL.\
                     0: BPDU packets are passed according to RTU rules only if PASS_ALL is set.[ML by modified]";

			prefix = "PASS_BPDU";
			
			type = BIT;
			access_dev = READ_ONLY;
			access_bus = READ_WRITE;
	 };

	 field {
			name = "Fix priority";
			description = "1: Port has fixed priority of value PRIO_VAL. It overrides the priority coming from the endpoint\
                     0: Use priority from the endpoint";

			prefix = "FIX_PRIO";
			
			type = BIT;
			access_dev = READ_ONLY;
			access_bus = READ_WRITE;
	 };


	 field {
			name = "Priority value";
			description = "Fixed priority value for the port. Used instead the endpoint-assigned priority when FIX_PRIO = 1";

			prefix = "PRIO_VAL";
			
			type = SLV;
			align = 4;
			size =3 ;
			access_dev = READ_ONLY;
			access_bus = READ_WRITE;
	 };


	 field {
			name = "Unrecognized request behaviour";
			description = "Sets the port behaviour for all unrecognized requests:\
                     0: packet is dropped\
                     1: packet is broadcast";
			prefix = "B_UNREC";
			
			type = BIT;
			access_dev = READ_ONLY;
			access_bus = READ_WRITE;

	 };

	 -- Mirroring Control fields go here.

};


peripheral {
	 name = "Routing Table Unit (RTU)";
   prefix="rtu";

	 hdl_entity="wrsw_rtu_wb";
	 
-- Port Configuration Register


	 reg {
			name = "RTU Global Control Register";
			description = "Control register containing global (port-independent) settings of the RTU.";
			prefix = "GCR";

			field {
				 name = "Main table bank select";
				 description = "Selects active bank of RTU hashtable (ZBT).\
				                0: bank 0 is used by lookup engine and bank 1 can be accessed using MFIFO\
				                1: bank 1 is used by lookup engine and bank 0 can be accessed using MFIFO";
				 type = BIT;			 
				 prefix = "HT_BSEL";
				 access_dev = READ_ONLY;
				 access_bus = READ_WRITE;
			};

			field {
				 name = "Hash collision table (HCAM) bank select";
				 description = "Selects active bank of RTU extra memory for colliding hashes.\
				                0: bank 0 is used by lookup engine\
				                1: bank 1 is used by lookup engine";
				 type = BIT;		 
				 prefix = "HCAM_BSEL";
				 access_dev = READ_ONLY;
				 access_bus = READ_WRITE;
			};

			field {
				 name = "RTU Global Enable";
				 description = "Global RTU enable bit. Overrides all port settings.\
                        0: RTU is disabled. All packets are dropped.\
                        1: RTU is enabled.";

				 type = BIT;
				 prefix = "G_ENA";
				 access_dev = READ_ONLY;
				 access_bus = READ_WRITE;
			};

			field {
				 name = "Hash Poly";
				 description = "Determines the polynomial used for hash computation. Currently available:  0x1021, 0x8005, 0x0589 ";

 				 type = SLV;
				 prefix = "POLY_VAL";
			 	 align = 8;
				 size = 16 ;
				 access_dev = READ_ONLY;
				 access_bus = READ_WRITE;
			};


			 clock = "zbt_clk_i";
	 };

-- TXTSU interrupts
	irq {
		 name = "UFIFO Not Empty IRQ";
		 description = "Interrupt active when there are some requests in UFIFO.";
		 prefix = "nempty";
		 trigger = LEVEL_0;
	};

	fifo_reg {
		 name = "Unrecognized request FIFO (UFIFO)";
		 description = "FIFO containing all RTU requests for which matching entries haven't been found. CPU reads these requests,\
		                evaluates them and updates the RTU tables accordingly.";

		 prefix = "UFIFO";
		 direction = CORE_TO_BUS;
		 size = 128;

		 flags_dev = {FIFO_FULL, FIFO_EMPTY};
		 flags_bus = {FIFO_EMPTY, FIFO_COUNT};

		 --clock = "zbt_clk_i";
		  -- clock = ""; - make it asynchronous if you want

		 field {
				name = "Destination MAC address least-significant part";
				description = "Bits [31:0] of packet destination MAC address";
				prefix = "DMAC_LO";

				type = SLV;
				size = 32;
		 };

	 field {
				name = "Destination MAC address most-significant part";
				description = "Bits [47:32] of packet destination MAC address";
				prefix = "DMAC_HI";

				type = SLV;
				size = 16;
		 };

		 field {
				name = "Source MAC address least-significant part";
				description = "Bits [31:0] of packet source MAC address";
				prefix = "SMAC_LO";

				type = SLV;
				size = 32;
		 };


		 field {
				name = "Source MAC address most-significant part";
				description = "Bits [47:32] of packet source MAC address";
				prefix = "SMAC_HI";

				type = SLV;
				size = 16;
		 };

		 field {
				name = "VLAN Identifier";
				description = "VLAN ID of the packet (from the endpoint)";
				prefix = "VID";
				size = 12;
				type = SLV;
				align = 32;
		 };

		 field {
				name = "Priority";
				description = "Priority value (from the endpoint)";
				prefix = "PRIO";
				size = 3;
				align = 4;
				type = SLV;
		 };

		 field {
				name = "Port ID";
				description = "Identifier of RTU port to which came the request.";
				prefix = "PID";
				size = 4;
				align = 4;
				type = SLV;
		 };

		 field {
				name = "VID valid";
				description = "1: VID value is valid\
                       0: packet had no VLAN ID";
				prefix = "HAS_VID";
			
				align = 4;
				type = BIT;
		 };

		 field {
				name = "PRIO valid";
				description = "1: PRIO value is valid\
                       0: packet had no priority assigned";
				prefix = "HAS_PRIO";
			
				type = BIT;
		 };
	};

	ram {
		 name = "Hash collisions memory (HCAM)";
		 description = "Memory block containing the 'tails' for hashes which have more than 4 entries and don't fit into a single bucket of main ZBT hashtable. \
		                <b>Note:</b> MSB of the address is the bank select bit. ";
		 prefix = "HCAM";

		 width = 32;
		 size = 32 * 8 * 2; -- 32 entries * 8 words per entry * 2 banks
		 access_dev = READ_ONLY;
		 access_bus = READ_WRITE;
		 
		 clock = "zbt_clk_i"; --async?

	};


	ram {
		 name = "Aging bitmap for main hashtable";
		 description = "Each bit in this memory reflects the state of corresponding entry in main hashtable:\
                    0: entry wasn't matched\
                    1: entry was matched at least once.\
                    CPU reads this bitmap and subsequently clears it every few seconds to update the aging counters.";
		 prefix = "ARAM_MAIN";

		 width = 32;
		 size = 8192 / 32; -- 8192 bits
		 access_dev = READ_WRITE;
		 access_bus = READ_WRITE;
		 
		 --[changed 6/10/2010] clock = "zbt_clk_i";
		 --clock = "zbt_clk_i"; --async?

	};

	ram {
		 name = "VLAN table (VLAN_TAB)";
		 description = "It stores VLAN-related information identified by VLAN ID (VID)";
		 prefix = "VLAN_TAB";

		 width = 32;
		 size = 4096 ; -- 4096 entries as defined in 802.1Q-2005, page 12
		 access_dev = READ_ONLY;
		 access_bus = READ_WRITE;
		 
		 -- --[changed 6/10/2010]  clock = "zbt_clk_i";
		 --clock = "zbt_clk_i"; --async?

	};

	reg {
		 name = "Aging register for HCAM";
		 description = "Each bit in this register reflects the state of corresponding entry in HCAM:\
                    0: entry wasn't matched\
                    1: entry was matched at least once.\
                    CPU reads this bitmap and subsequently clears it every few seconds to update the aging counters.";
		 prefix = "AGR_HCAM";

		 field {
				name = "Aging register value";
				type = SLV;
				size = 32;
				access_dev = READ_WRITE;
				access_bus = READ_WRITE;
				load = LOAD_EXT;
		 };
		 
		 clock = "zbt_clk_i";
--		 clock = "zbt_clk_i"; --async?

	};


	fifo_reg {
		 name = "Main hashtable CPU access FIFO (MFIFO)";
		 description = "FIFO for writing to main hashtable";
		 prefix = "MFIFO";
		 direction = BUS_TO_CORE;
		 size = 64;

		 flags_dev = {FIFO_EMPTY, FIFO_COUNT};
		 flags_bus = {FIFO_EMPTY, FIFO_FULL, FIFO_COUNT};

		 
		 field {
				name = "Address/data select";
				description = "1: AD_VAL contains new memory address\
				               0: AD_VAL contains data word to be written at current memory address. Then, the address is incremented";
				prefix = "AD_SEL";
				type = BIT;
		 };

		 field {
				name = "Address/data value";
				description = "Value of new memory address (when AD_SEL = 1) or data word to be written (when AD_SEL = 0)";
				prefix = "AD_VAL";
				type = SLV;
				align =32;
				size = 32;
		 };

		 clock = "zbt_clk_i";

	};

};


function gen_PCRs(num_pcrs)
	 local i;
	 
	 for i=0,num_pcrs-1 do
			local rp = deepcopy(PCR_template);
			rp.name = rp.name.." "..i;
			rp.prefix = rp.prefix..i;
			table.insert(periph, rp);
	 end
end

gen_PCRs(10);
