⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macro_usage.uc

📁 国内还比较新的network processor的微代码开发
💻 UC
📖 第 1 页 / 共 2 页
字号:

	// Enable timestamp for all microengines so that cycle counter can
	// get updated every 16 cycles

	// MEs should read the value of MISC_CONTROL, OR-in 0x80, and then write 
	// that value back. So that it doesnt overwrite its default value

	cap[read, $sxfer, MISC_CONTROL], ctx_swap[cap_sig]
	alu[$sxfer, $sxfer, OR, 0x80]
   	cap[fast_wr, ALU, MISC_CONTROL]   
								    
	// 28 nops for the timestamp enabling to take effect
	nop 
	nop 
	nop 
	nop
	nop
	nop
	nop
	nop 
	nop 
	nop 
	nop
	nop
	nop
	nop
	nop 
	nop 
	nop 
	nop
	nop
	nop
	nop
	nop 
	nop 
	nop 
	nop
	nop
	nop
	nop

	// Read the low 32-bit value from cycle counter
	cycle32_read(out_cycle1)

	// Wait approx 40 cycles for cycle counter to update
	//	(approx 3-4 units from cycle counter)
	cycle32_delay(40)

	// Now read another low 32-bit value from cycle counter
	cycle32_read(out_cycle2)

	// Get elapsed time between the two cycle reads
	cycle32_diff(out_diff, out_cycle2, out_cycle1)

	put_nv(cycle1, out_cycle1)
	put_nv(cycle2, out_cycle2)
	put_nv(diff, out_diff)

	// Put the current context in sleep mode for approx 80 cycles
	cycle32_sleep(80)

.end
#endm

// ==================================================================
// 	This demonstrates the usage of SRAM macros
// ==================================================================
#macro sram_examples()
.begin
	.reg sram_base_addr, sram_offset, lw_count

	// Declare signals to be used with SRAM operations
	.sig SRAM_SIG1 SRAM_SIG2

	// Allocate buffer of Xfer registers
	xbuf_alloc($xfer, 3, read_write)

	move($xfer[0], 0xFFFFFFFF)
	move($xfer[1], 0x1111111)
	move($xfer[2], 0x222222)

	// Write to SRAM at sram_base_addr=24, sram_offset=0, lw_count=1
	//	Context swap until the write is done; waken up by SRAM_SIG1 signal
	// Location1 = 0xFFFFFFFF
	immed32(sram_base_addr, 24)
	immed32(sram_offset, 0)
	immed32(lw_count, 1)
	sram_write($xfer[0], sram_base_addr, sram_offset, lw_count, SRAM_SIG1, SRAM_SIG1, ___)

	// ---> First write is complete

	// Write to SRAM at base=50, sram_offset=32, lw_count=2
	//	Generate signal SRAM_SIG2 once the write is done but don't wait for
	//	the write to complete though
	// Location2_1 = 0x01111111
	// Location2_2 = 0x00222222
	sram_write($xfer[1], 50, 32, 2, SRAM_SIG2, SIG_NONE, ___)

	// ---> Second write is still outstanding

	// Get original value from the location of the first write to $xfer[0]; clear the
	//	low 4 bits of that value and write the result to the same location; generate
	//	signal SRAM_SIG1 once all operations are done. 
	// Before proceeding to the next instruction, wait for both signals SRAM_SIG1 and
	//	SRAM_SIG2
	// $xfer[0] = 0xFFFFFFFF
	sram_bits_test_and_clr($xfer[0], 0xF, 24, 0, SRAM_SIG1, signals(SRAM_SIG1, SRAM_SIG2), ___)

	// ---> All of the above SRAM operations are complete

	// Get 1 long-word of the original value from the location of the second write to
	//	$xfer[1]; set the low 4 bits of that value and write the result to the same
	//	location; context swap until all of these operations are done, signaled by SRAM_SIG1
	// $xfer[1] = 0x01111111; $xfer[2] = 0x00222222
	sram_bits_test_and_set($xfer[1], 0xF, 50, 32, SRAM_SIG1, SRAM_SIG1, ___)

	// ---> SRAM test and set operation is complete

	put_nv(xfer0, $xfer[0])
	put_nv(xfer1, $xfer[1])

	// Read from the location of the first write; generate signal SRAM_SIG1 once the
	//	read is done but don't wait for it to complete though
	// Location1 = $xfer[0] = 0xFFFFFFF0
	sram_read($xfer[0], 24, 0, 1, SRAM_SIG1, SIG_NONE, ___)

	// ---> First read is still outstanding

	// Read from the location of the second write; generate signal SRAM_SIG2 once the
	//	read is done; wait for both signals SRAM_SIG1 and SRAM_SIG2 before proceeding to
	//	the next instruction
	// Location2_1 = $xfer[1] = 0x0111111F
	// Location2_2 = $xfer[2] = 0x00222222
	sram_read($xfer[1], 50, 32, 2, SRAM_SIG2, signals(SRAM_SIG1, SRAM_SIG2), ___)

	// ---> All reads are complete

	put_nv(location1, $xfer[0])
	put_nv(location2_1, $xfer[1])
	put_nv(location2_2, $xfer[2])

	// Free buffer of Xfer registers
	xbuf_free($xfer)

.end
#endm

// ==================================================================
// This demonstrates the usage of LOCAL MEMORY macros
// ==================================================================
#macro localmemory_examples()
.begin
	.reg in_data1, in_data2, out_data1, out_data2
	// Examples
	//Local Memory Macros

	//
	// API:
	//	localmem_set_address(in_lmaddr, in_addr_offset, LM_HANDLE)
	//	localmem_set_active_handle(in_reg_num)
	//	localmem_read1(out_data, in_lmaddr, in_addr_offset)
	//  localmem_read2(out_data0, out_data1, in_lmaddr, in_addr_offset)
	//	...
	//	localmem_read8(out_data0, out_data1, out_data2, out_data3, out_data4, 
	//				   out_data5, out_data6, out_data7, in_lmaddr, in_addr_offset)
	//  localmem_write1(in_data, in_lmaddr, in_addr_offset)
	//  localmem_write2(in_data0, in_data1, in_lmaddr, in_addr_offset)
	//  ...
	//  localmem_write8(in_data0, in_data1, in_data2, in_data3, in_data4, in_data5, 
	//					in_data6, in_data7, in_lmaddr, in_addr_offset)
	//  localmem_read_next(out_data)
	//  localmem_write_next(in_data)

	#define_eval LM_BASE 	0

	alu[in_data1, --, B, 100]
	alu[in_data2, --, B, 200]
	// This will perform localmemory write of one long word to byte address (LM_BASE+64)
	localmem_write2(in_data1, in_data2, LM_BASE, 64);

	// This will perform localmemory read from by byte address (LM_BASE+64)
	localmem_read1(out_data1, LM_BASE, 64);

	// This will perform incremental read from the previous 
	localmem_read_next(out_data2);

	// display results
	put_nv(LM1, out_data1);
	put_nv(LM2, out_data2);

.end
#endm

// ==================================================================
// This demonstrates the usage of CAM macros
// ==================================================================
#macro cam_examples()
.begin
	// API:
	//	cam_clear_all ()
	//	cam_read_entry(out_data, out_state, in_entry_num)
	//	cam_write_entry(in_entry_num, in_data, in_state)
	//  cam_match(out_state, out_status, out_entry_num, in_data)

	// Clear all the cam entries first 
	cam_clear_all()

	// Fill up cam entries
	// Note last param is the state information that has to be a constant.
	cam_write_entry(0, 10, 5);	write to entry 0
	cam_write_entry(1, 11, 6);  write to entry 1
	cam_write_entry(2, 12, 7);  write to entry 2
	cam_write_entry(3, 13, 8);  write to entry 3
	cam_write_entry(4, 14, 9);  write to entry 4

	// Read from CAM enrty#3
	cam_read_entry(out_data, out_state, 3);

	// display values
	put_nv(CAM_O1, out_data);
	put_nv(CAM_S1, out_state);

	// Do a CAM lookup - with an existing entry
	cam_match(out_state, out_status, out_entry_num, 12);

	alu[--, --, B, out_status]

	// Check the lookup status, if 0 then no match else match found
	br=0[continue_cam#]
	// display the matched entry number
	put_nv(MATCHED, out_entry_num);
	put_nv(ST, out_state);

	continue_cam#:

	// do a CAM lookup with a non-existent entry e.g. 1
	cam_match(out_state, out_status, out_entry_num, 1);

	alu[--, --, B, out_status]

	// Check the lookup status, if 0 then no match else match found
	br!=0[end_cam#]
	// No matched entry found, so the out_entry_number contains 
	// the least recently used entry
	put_nv(LRU, out_entry_num);
	put_nv(ST, out_state);

end_cam#:
	nop;
	nop;
.end
#endm

// ==================================================================
// This demonstrates the usage of BUF macros
// ==================================================================
#macro buf_examples()
.begin
	// API
	// buf_dram_addr_from_index(out_address, in_index, POOL_ID, D_BASE, D_SIZE, S_BASE, S_SIZE)
	// buf_dram_addr_from_sram_addr(out_dram_addr, in_sram_addr, POOL_ID, D_BASE, D_SIZE, S_BASE, S_SIZE)
	// buf_index_from_sram_addr(out_index, in_address, POOL_ID, D_BASE, D_SIZE, S_BASE, S_SIZE)
	// buf_index_from_dram_addr(out_index, in_address, POOL_ID, D_BASE, D_SIZE, S_BASE, S_SIZE)
	// buf_sram_addr_from_index(out_address, in_index, POOL_ID, D_BASE, D_SIZE, S_BASE, S_SIZE)

	// Define FREELIST AS
	// POOL_ID = 1, 
	// d_base = 1024,
	// d_size = 128, 
	// s_base = 512, 
	// s_size = 32
	#define FREELIST	1, 1024, 128, 512, 32

	// set dram_index to a test value of 4	
	immed32(dram_index, 4);
	buf_dram_addr_from_index(out_address, dram_index, FREELIST);
	// display dram address
	put_nv(o1, out_address);	// expected value = (4*128 + 1024) = 1536

	// set sram_index to a test value of 20
	immed32(sram_index, 20);
	buf_sram_addr_from_index(sram_address, sram_index, FREELIST);
	// display sram address 
	put_nv(o2, sram_address);		// expected value = (20*32 + 512) = 1152
	
	// set sram_address to a test value of 2048
	immed32(sram_addr, 2048);
	buf_dram_addr_from_sram_addr(out_address, sram_addr, FREELIST);
	put_nv(o3, out_address);	// expected value = ((((2048-512)/32)*128) + 1024) = 7168

	// set sram_address to a test value of 2048	
	immed32(sram_address, 2048);
	buf_index_from_sram_addr(out_index, sram_address, FREELIST);
	put_nv(o4, out_index);	// expected value = ((2048-512)/32) = 48

	// set dram_address to a test value of 2048	
	immed32(dram_address, 2048);
	buf_index_from_dram_addr(out_index, dram_address, FREELIST);
	put_nv(o5, out_index); // expected value = ((2048-1024)/128) = 8

.end
#endm

// ==================================================================
// This demonstrates the usage of XBUF macros, particularly with
// local memory buffers.
// ==================================================================

// macro for xbuf_examples
#macro first_block(xname, result, thread_id)
	xbuf_activate(xname, 1, thread_id, 1)	// select handle1, thread0
	// uses of xname:
	// 		xbuf_extract(..., xname, ...)
	//		xbuf_copy(xname, ...)
	move(xname[0], 0x12345678)
	xbuf_extract(result, xname, 0, 0, 2)
	xbuf_deactivate(xname)
#endm
// macro for xbuf_examples
#macro second_block(xname, result, thread_id)
	xbuf_activate(xname, 0, thread_id, 1)	// select handle0, thread0
	// uses of xname:
	// 		xbuf_extract(..., xname, ...)
	//		xbuf_copy(xname, ...)
	move(xname[0], 0xABCDEF90)
	xbuf_extract(result, xname, 0, 0, 3)
	xbuf_deactivate(xname)
#endm

#macro xbuf_examples()
.begin
.reg result offset t_id
.sig SIG0
#define_eval ipv4_hdr		lmem_buf0
#define_eval ipv6_hdr		lmem_buf1

// begin examples for ipv4_hdr
// ---------------------------
#define_eval POOLS_BASE		0x100
#define_eval POOL_SIZE		0x100
#define_eval BUFFER_OFFSET	0x0

immed[t_id, 0]
xbuf_alloc(ipv4_hdr, 8, read_write)
xbuf_bind_address(ipv4_hdr, POOLS_BASE, POOL_SIZE, BUFFER_OFFSET)

first_block(ipv4_hdr, result, t_id)
put_nv(e1, result)		// expect 0x1234
second_block(ipv4_hdr, result, t_id)
put_nv(e2, result)		// expect 0xABCDEF

xbuf_free(ipv4_hdr)
// end examples for ipv4_hdr
// -------------------------

// begin examples for ipv6_hdr
// ---------------------------
#define_eval POOLS_BASE		0x200
#define_eval POOL_SIZE		0x80
#define_eval BUFFER_OFFSET	0x0

immed[offset, 0]
xbuf_alloc(ipv6_hdr, 16, read_write)
xbuf_bind_address(ipv6_hdr, POOLS_BASE, POOL_SIZE, BUFFER_OFFSET)

// associate with handle 0
xbuf_activate(ipv6_hdr, 0, t_id, 0)
// uses of ipv6_hdr
move(ipv6_hdr[0], 0xA0B0C0D0)
move(ipv6_hdr[1], 0xA1B1C1D1)
move(ipv6_hdr[2], 0xA2B2C2D2)
move(ipv6_hdr[3], 0xA3B3C3D3)
move(ipv6_hdr[4], 0xA4B4C4D4)

xbuf_alloc($$dram_w, 2, write)
xbuf_alloc($$dram_r, 2, read)
move($$dram_w0, 0)
move($$dram_w1, 0)

// copy 8 bytes from ipv6_hdr to $$dram_w
xbuf_copy($$dram_w, 0, offset, ipv6_hdr, 4, 0, 8, 0)

dram_write($$dram_w0, 0x100, 0, 1, SIG0, SIG0, ___)
dram_read($$dram_r0, 0x100, 0, 1, SIG0, SIG0, ___)
put_nv(d0, $$dram_r0)		// expect 0xA1B1C1D1
put_nv(d1, $$dram_r1)		// expect 0xA2B2C2D2

xbuf_deactivate(ipv6_hdr)

// associate with handle 1 
xbuf_activate(ipv6_hdr, 1, t_id, 1)

move($$dram_w0, 0x11223344)
move($$dram_w1, 0xAABBCCDD)
dram_write($$dram_w0, 0x100, 0, 1, SIG0, SIG0, ___)
dram_read($$dram_r0, 0x100, 0, 1, SIG0, SIG0, ___)

// copy 8 bytes from $$dram_r to ipv6_hdr
xbuf_copy(ipv6_hdr, 0, 0, $$dram_r, offset, 0, 8, 0)

put_nv(l0, ipv6_hdr[0])		// expect 0x11223344
put_nv(l1, ipv6_hdr[1])		// expect 0xAABBCCDD

xbuf_deactivate(ipv6_hdr)

xbuf_free($$dram_w)
xbuf_free($$dram_r)
xbuf_free(ipv6_hdr)
// end examples for ipv6_hdr
// -------------------------
.end
#endm

// ==================================================================
// Start running the example macros
// ==================================================================

scratch_examples_1()
scratch_examples_2()
dram_examples()
cycle_examples();
sram_examples();
cam_examples();
localmemory_examples();
buf_examples();
xbuf_examples();

put_nv(DONE, 1);

End_of_program#:
nop
nop
nop
nop
ctx_arb[voluntary]
br[End_of_program#]

// ==================================================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -