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

📄 macro_usage.uc

📁 国内还比较新的network processor的微代码开发
💻 UC
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------------
//                                                                     
//                  I N T E L   P R O P R I E T A R Y                   
//                                                                      
//     COPYRIGHT (c)  2001 BY  INTEL  CORPORATION.  ALL RIGHTS          
//     RESERVED.   NO  PART  OF THIS PROGRAM  OR  PUBLICATION  MAY      
//     BE  REPRODUCED,   TRANSMITTED,   TRANSCRIBED,   STORED  IN  A    
//     RETRIEVAL SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR COMPUTER    
//     LANGUAGE IN ANY FORM OR BY ANY MEANS, ELECTRONIC, MECHANICAL,    
//     MAGNETIC,  OPTICAL,  CHEMICAL, MANUAL, OR OTHERWISE,  WITHOUT    
//     THE PRIOR WRITTEN PERMISSION OF :                                
//                                                                      
//                        INTEL  CORPORATION                            
//                                                                     
//                     2200 MISSION COLLEGE BLVD                        
//                                                                      
//               SANTA  CLARA,  CALIFORNIA  95052-8119                  
//                                                                      
//-----------------------------------------------------------------------------------
// macro_usage.uc
// Example to demonstrate the usage of ixpblock macros
//
//
#include "buf.uc"
#include "bytefield.uc"
#include "cam.uc"
#include "constants.uc"
#include "cycle.uc"
#include "dram.uc"
#include "localmem.uc"
#include "scratch.uc"
#include "sig.uc"
#include "sram.uc"
#include "stdmac.uc"
#include "util.uc"
#include "xbuf.uc"

#include "put_nv.uc"

// ==================================================================
// 	This demonstrates the usage of SCRATCH macros
// ==================================================================
#macro scratch_examples_1()
.begin
	.sig tmp_sig1 tmp_sig2 tmp_sig3 tmp_sig4 SIG_SRAM

	///////////////////////////////////////////////////////////////////////////////////////
	// Example 1: This example shows the usage of Scratch read/write macros. It illustrate the
	//			  following points via different tasks:
	//
	//			  1) Allocate a transfer buffers of 8 registers
	//				 Illustrate: Usage of transfer buffers as source of scratch read and
	//							  destination of scratch write
	//			  2) Write 4 long words to a random base and a random multiply-of-4
	//			     offset in scratch memory. Subsequent writes don't have to wait for this
	//				 write to complete
	//				 Illustrate: - Offsets of all scratch accesses must be multiple of 4
	//							 - The unit of access for Scratch memory is long words (4 bytes)
	//							 - Usage of SIG_NONE in accesses that can happen in parallel
	//			  3) Write another 4 long words to another random location. This write will have
	//				 to finish before the read in task 4
	//				 Illustrate: - Usage of signals to make sure an access is finished before
	//							   next accesses
	//			  4) Read all 8 long words at the location written before
	//				 Illustrate: - Each xfer registers allocated by xbuf_alloc include
	//							   1 SRAM read transfer register and 1 SRAM write transfer
	//							   register. The instruction will select the right type of
	//							   register to use
	//		       5) Free the transfer buffers
	////////////////////////////////////////////////////////////////////////////////////////
	// Allocate buffer of Xfer registers

	xbuf_alloc($xfer, 8, read_write)

	//Initialize the write transfer registers
	move($xfer[0], 0xFFFFFFFF)
	move($xfer[1], 0x1111111)
	move($xfer[2], 0x222222)
	move($xfer[3], 0x33333)
	move($xfer[4], 0x4444)
	move($xfer[5], 0x555)
	move($xfer[6], 0x66)
	move($xfer[7], 0x7)

	immed32(base, 0x1000);
	alu[offset1, --, b, 0x10]
	alu[offset2, --, b, 0x20]

	//Task 1: write from the write transfer regsiters
	scratch_write($xfer[0], base, offset1, 4, tmp_sig1, SIG_NONE, ___);

	//Task 2
	scratch_write($xfer[4], base, offset2, 4, tmp_sig2, signals(tmp_sig1, tmp_sig2), ___);

	//Task 3: read into the read transfer registers
	scratch_read($xfer[0], base, offset1, 8, SIG_SRAM, SIG_SRAM, ___);

	//Display the read result
	put_nv(x0, $xfer[0]);
	put_nv(x1, $xfer[1]);
	put_nv(x2, $xfer[2]);
	put_nv(x3, $xfer[3]);
	put_nv(x4, $xfer[4]);
	put_nv(x5, $xfer[5]);
	put_nv(x6, $xfer[6]);
	put_nv(x7, $xfer[7]);

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


	///////////////////////////////////////////////////////////////////////////////////////
	// Example 2: This example shows the usage of Scratch read/write macros. It illustrates the
	//			  following points via different tasks:
	//
	//			  1) Allocate local transfer registers
	//				 Illusttrate: Using transfer registers in Scratch macros
	//
	//			  2) 3 writes of 4 long words each to a random base and random multiply-of-4
	//			     offsets in scratch memory. Subsequent accesses don't have to wait for previous
	//				 write to complete
	//
	//			  3) Write 4 more long words to another address. Subsequent accesses will have
	//				 to wait for all 3 writes
	//				  Illustrate: the number of signals in in_wait_sigs is not limited to 2
	//
	//			  4) Read all 8 long words at the location written before
	//				 
	////////////////////////////////////////////////////////////////////////////////////////
	// Allocate buffer of Xfer registers

	.reg		$w_xfer0 $w_xfer1 $w_xfer2 $w_xfer3 $w_xfer4 $w_xfer5 $w_xfer6 $w_xfer7 \
		   		$w_xfer8 $w_xfer9 $w_xfer10 $w_xfer11 \
				$r_xfer0 $r_xfer1 $r_xfer2 $r_xfer3 $r_xfer4 $r_xfer5 $r_xfer6 $r_xfer7 \
		   		$r_xfer8 $r_xfer9 $r_xfer10 $r_xfer11 \
				base_addr

	.xfer_order $r_xfer0 $r_xfer1 $r_xfer2 $r_xfer3 $r_xfer4 $r_xfer5 $r_xfer6 $r_xfer7 \
		   		$r_xfer8 $r_xfer9 $r_xfer10 $r_xfer11
			
	.xfer_order	$w_xfer0 $w_xfer1 $w_xfer2 $w_xfer3 $w_xfer4 $w_xfer5 $w_xfer6 $w_xfer7 \
		   		$w_xfer8 $w_xfer9 $w_xfer10 $w_xfer11


	//Initilize write transfer registers
	#define_eval INDEX	  0
	#define_eval TEST_VAL 0x11111111
	#while (INDEX < 12)
		immed32($w_xfer/**/INDEX/**/, TEST_VAL);
		#define_eval	INDEX (INDEX+1)
		#define_eval TEST_VAL	TEST_VAL*2
	#endloop

	immed32(base_addr, 0x1000);
	alu[offset1, --, b, 0x10]
	alu[offset2, --, b, 0x20]

	//Task 1
	scratch_write($w_xfer0, base_addr, offset1, 4, tmp_sig1, SIG_NONE, ___);

	//Task 2
	scratch_write($w_xfer4, base_addr, offset2, 4, tmp_sig2, SIG_NONE, ___);

	//Task 3
	alu[offset2, --, b, 0x40]

	scratch_write($w_xfer8, base_addr, offset2, 4, tmp_sig3, signals(tmp_sig1, tmp_sig2, tmp_sig3), ___);

	//Task 4
	scratch_read($r_xfer0, base_addr, offset1, 8, tmp_sig4, SIG_NONE, ___);

	scratch_read($r_xfer8, base_addr, offset2, 4, SIG_SRAM, signals(SIG_SRAM, tmp_sig4), ___);

	//display the result using put_nv debug utility
	#define_eval INDEX	0
	#while (INDEX < 12)
		put_nv(r/**/INDEX/**/, $r_xfer/**/INDEX/**/);
		#define_eval	INDEX (INDEX+1)
	#endloop

	.end
#endm

// ==================================================================
// 	This demonstrates the usage of SCRATCH macros
// ==================================================================
#macro scratch_examples_2
.begin

	///////////////////////////////////////////////////////////////////////////////////////
	// Example 3: This example shows the use of Scratch read/write macros. It illustrates the 
	//			  following points:
	//
	//			  1) Allocate a transfer buffers with 16 registers
	//			  2) Write 6 long words (8 bytes) to a random base_addr and a random multiply-of-4
	//			     offset in scratch memory. Subsequent writes don't have to wait for this
	//				 write to complete
	//
	//			  3) Write 6 other long words to another random location. This write will have
	//				 to before the read in task 4
	//							   
	//			  4) Read all 12 long words at the location written before
	//				 Illustrate: - If we want to access more than 8 long words we must
	//								do indirect access (meaning the counts of words must be in 
	//								general register)
	////////////////////////////////////////////////////////////////////////////////////////
	// Allocate buffer of Xfer registers
	.reg base_addr offset lw_count
	xbuf_alloc($xfer1, 12, read_write)

	#define_eval INDEX	0
	#while (INDEX < 12)
		immed32($xfer1[/**/INDEX/**/], INDEX);
		#define_eval	INDEX (INDEX+1)
	#endloop

	immed32(base_addr, 0x1000);
	alu[offset1, --, b, 0x0]
	alu[offset2, --, b, 0x20]

	//Task 2
	scratch_write($xfer1[0], base_addr, offset1, 6, tmp_sig1, SIG_NONE, ___);
	//Task 3
	scratch_write($xfer1[6], base_addr, offset2, 6, tmp_sig3, signals(tmp_sig1, tmp_sig3), ___);

	//Task 4
	alu[lw_count, --, b, 12]
	scratch_read($xfer1[0], base_addr, offset1, lw_count, tmp_sig2, tmp_sig2, ___);

	#define_eval	INDEX	(0)
	#while (INDEX < 12)
		put_nv(x/**/INDEX/**/, $xfer1[/**/INDEX/**/]);
		#define_eval	INDEX (INDEX+1)
	#endloop

	// Free buffer of Xfer registers
	xbuf_free($xfer1);

	///////////////////////////////////////////////////////////////////////////////////////
	// Example 4: This example shows the use of Scratch_bits_clr and scratch_bits_set macro
	//
	//			  Illustrate: uasge of the mask:	
	//						   + each binary digit in the mask correspond to a bit in the 
	//							 data to be cleared or set 
	//						  
	////////////////////////////////////////////////////////////////////////////////////////
	.reg $w_xfer0 $r_xfer0

	immed32($w_xfer0, 0xfffffffe);

	alu[base_addr, --, b, 32]

	scratch_write($w_xfer0, base_addr, 0, 1, tmp_sig1, tmp_sig1, ___);

	scratch_bits_clr(0xf0, base_addr, 0, tmp_sig1, tmp_sig1, ___);
	scratch_bits_set(0x1, base_addr, 0, tmp_sig2, tmp_sig2, ___);

	scratch_read($r_xfer0, base_addr, 0, 1, tmp_sig1, tmp_sig1, ___);

	//print expected result: 0xffffff0f
	put_nv(result, $r_xfer0); 


	///////////////////////////////////////////////////////////////////////////////////////
	// Example 4: This example shows the use of Scratch_bits_test_and_clr and 
	//			  scratch_bits_test_and_set macro
	//
	//			  Illustrate: 
	//					- uasge of the mask: similar to in scratch_bits_clr and
	//						  scratch_bits_set
	//					- besides clearing/setting the bits specified in the masks,
	//							the original value is saved in the out_data operand	
	//						  
	////////////////////////////////////////////////////////////////////////////////////////
	.reg $org_data $immed_result $test_result mask1 mask2

	immed32($org_data, 0x12345678);

	immed32(mask1, 0xff00);
	immed32(mask2, 0x71000000);

	alu[base_addr, --, b, 0x64]
	alu[offset, --, b, 0x8]

	scratch_write($org_data, base_addr, offset, 1, tmp_sig1, tmp_sig1, ___);

	scratch_bits_test_and_clr($immed_result, mask1, base_addr, offset, tmp_sig2, tmp_sig2, ___);

	scratch_bits_test_and_set($test_result, mask2, base_addr, offset, tmp_sig2, tmp_sig2, ___);

	scratch_read($result, base_addr, offset, 1, tmp_sig1, tmp_sig1, ___);

	// print expected value: 0x12345678
	put_nv(org, $immed_result);
	// print 0x12340078
	put_nv(immediate, $test_result);
	//print 0x73340078
	put_nv(result, $result);

.end
#endm

// ==================================================================
// 	This demonstrates the usage of SRAM macros
// ==================================================================
#macro dram_examples
.begin

	.sig tmp_sig5 SIG_DRAM 

	///////////////////////////////////////////////////////////////////////////////////////
	// Example 1: This example shows the usage of DRAM read/write macros. It illustrates the
	//			  following points via diffrent tasks:
	//
	//			  1) Allocate a transfer buffers of 16 registers
	//				 Illustrate: Each DRAM access is a quad word (8 bytes). Each DRAM transfer register is
	//							 4-byte long. So, for 8 DRAM accesses, you need 16 DRAM registers
	//
	//			  2) 2 writes, each writes 2 quad words to a random base and a random multiply-of-8
	//			     offset in DRAM memory. Subsequent writes don't have to wait for previous
	//				 writes to complete
	//				 Illustrate: - Offsets of all DRAM accesses must be multiple of 8
	//							 - The unit of access for DRAM memory is quad words (8 bytes)
	//							 - DRAM accesses always have to use signal with even number
	//							   but the assembler takes care of that
	//							 - Usage of SIG_NONE for accesses that can happen in parallel
	//
	//			  3) Write another 2 words to another random location. This write will have
	//				 to finish before the read in task 4
	//				 Illustrate: - Usage of signals to make sure an access is finished before
	//							   next accesses
	//							 - Name can be in capital as SIG_DRAM. This name is similar to 
	//							   naming conmvention in IXP1200 macros, if any users used this before
	//							 - The number of signals doesn't have to be 2
	//
	//			  4) Read all 6 quad words at the location written before
	//			
	////////////////////////////////////////////////////////////////////////////////////////

	.reg 		$$wreg0 $$wreg1 $$wreg2 $$wreg3 $$wreg4 $$wreg5 $$wreg6 $$wreg7 \
				$$wreg8 $$wreg9 $$wreg10 $$wreg11 \
				$$rreg0 $$rreg1 $$rreg2 $$rreg3 $$rreg4 $$rreg5 $$rreg6 $$rreg7 \
				$$rreg8 $$rreg9 $$rreg10 $$rreg11 \
				base_addr

	.xfer_order $$wreg0 $$wreg1 $$wreg2 $$wreg3 $$wreg4 $$wreg5 $$wreg6 $$wreg7 \
				$$wreg8 $$wreg9 $$wreg10 $$wreg11

	.xfer_order $$rreg0 $$rreg1 $$rreg2 $$rreg3 $$rreg4 $$rreg5 $$rreg6 $$rreg7 \
				$$rreg8 $$rreg9 $$rreg10 $$rreg11

	#define_eval 	TEST_VAL	0x11111111
	#define_eval 	INDEX	0

	#while (INDEX < 12)
		immed32($$wreg/**/INDEX/**/, TEST_VAL);
		#define_eval	INDEX (INDEX+1)
		#define_eval 	TEST_VAL	TEST_VAL*2
	#endloop

	alu[base_addr, --, b, 0]

	//since tmp_sig1, tmp)_sig2, tmp_sig3, tmp_sig5 are used for DRAM accesses,
	//the assembler will assigned even-numbered signals to them. Also, the odd-numbered
	//signals corresponding to them will be reserved and used
	dram_write($$wreg0, base_addr, 0x10, 2, tmp_sig1, SIG_NONE, ___);
	dram_write($$wreg4, base_addr, 0x20, 2, tmp_sig2, SIG_NONE, ___);

	dram_write($$wreg8, base_addr, 0x30, 2, tmp_sig4, signals(tmp_sig1,tmp_sig2,tmp_sig4), ___);

	dram_read($$rreg0, base_addr, 0x10, 6, SIG_DRAM, SIG_DRAM, ___);

	#define_eval	INDEX	(0)
	#while (INDEX < 12)
	    put_nv(wr/**/INDEX/**/, $$rreg/**/INDEX/**/);
		#define_eval	INDEX (INDEX+1)
	#endloop


	///////////////////////////////////////////////////////////////////////////////////////
	// Example 2: This example illutrates the usage of DRAM read/write and dram_mask_write
	//			  macros. It illustrate the following points via different tasks:
	//
	//			  1) Allocate a transfer buffers of 16 registers
	//				 Illustrate: Each DRAM access is a quad word (8 bytes). Each DRAM transfer register is
	//							 4-byte long. So, for 8 DRAM accesses, you need 16 DRAM registers
	//
	//			  2) 1 writes to a random base and a random multiply-of-8
	//			     offset in DRAM memory. Subsequent instructions don't have to wait for
	//				 the write to complete
	//				 Illustrate: - Base can be random number -- doesn't have to be multiple of 8 as offset
	//							 - Usage of one signal as both request signal and wait signal
	//
	//			  3) A mask-write another 2 words to the same location
	//				 Illustrate: - Usage of a mask:.
	//									+ each bit in the mask correspond to a byte. The order
	//									  is from left to right							    
	//									+ A 1 in the mask means the byte will be overwritten 
	//			  4) Read the quad word at the location written before
	//			
	////////////////////////////////////////////////////////////////////////////////////////
	xbuf_alloc($$xfer, 4, read_write);

	immed32($$xfer[0], 0xe8773dd3);
	immed32($$xfer[1], 0x0f7357ef);

	immed32($$xfer[2], 0x45118922);
	immed32($$xfer[3], 0xad80fd90);

	immed32(base_addr, 0x0838f766);
	alu[offset, --, b, 0x20]
	alu[mask, --, b, 0xf7]

	dram_write($$xfer[0], base_addr, offset, 1, tmp_sig2, tmp_sig2, ___);

	dram_mask_write($$xfer[2], base_addr, offset, mask, tmp_sig5, tmp_sig5, ___);

	dram_read($$xfer[0], base_addr, offset, 1, tmp_sig3, tmp_sig3, ___);

	//print 0xe8118922
	put_nv(x0, $$xfer[0]);
	//print 0xad80fd90
	put_nv(x1, $$xfer[1]);

	xbuf_free($$xfer);
.end
#endm



// ==================================================================
// 	This demonstrates the usage of CYCLE macros
// ==================================================================
#macro cycle_examples()
.begin
	.reg out_cycle1 out_cycle2 out_diff

	// sxfer reg to read and write misc_control reg
	.reg $sxfer
	.sig cap_sig

⌨️ 快捷键说明

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