📄 macro_usage.uc
字号:
// 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 + -