EM78xxx单芯片微控制器13位指令集详解

需积分: 5 0 下载量 2 浏览量 更新于2024-07-09 收藏 573KB PDF 举报
"该文档是关于EM78xxx系列13位指令集的高质量中文翻译,主要涵盖了微控制器的指令操作、特点以及一系列指令的详细描述。" EM78xxx系列是一款基于精简指令集(RISC)架构的单片机,其指令系统以13位字节为基础,每个指令由OP代码和零个或多个操作数组成。大部分指令在一个指令周期内执行,但执行特定指令如"MOVR2,A"、"ADDR2,A"、"LCALL"或"LJMP"时,可能需要两个指令周期。这款微控制器具有以下显著特点: 1. **任意寄存器位操作**:允许对任何寄存器的单独位进行设置、清除或直接测试,增强了数据处理的灵活性。 2. **通用I/O寄存器**:I/O寄存器可以像通用寄存器一样被访问,使用相同的指令集,这使得数据输入输出和内部处理更为便捷。 文档中详细列出了EM78xxx的指令集,包括但不限于: - **ADD**和**ADDC**:实现加法操作,前者不考虑进位,后者考虑进位。 - **AND**:按位与操作,用于进行位逻辑运算。 - **BS**和**BC**:位清除和位设置,分别用于清零和置一特定位。 - **CALL**:子程序调用,用于执行子程序并保留返回地址。 - **CLR**和**CLRA**:清除指定寄存器或累加器A的所有位。 - **COM**和**COMA**:对寄存器或累加器A进行补码操作。 - **CONT**和**CONTW**:控制寄存器的转移。 - **DAA**:二进制调整辅助指令,用于调整加法后的结果。 - **DEC**和**DECA**:减1操作,减完后将结果存储回原寄存器或累加器A。 - **DISI**:禁止中断,确保在关键操作期间不受外部中断影响。 - **DJZ**和**DJZA**:根据寄存器或累加器A的值是否为0决定是否跳过下一条指令。 - **ENI**:启用中断,允许中断请求被响应。 - **INC**和**INCA**:加1操作,增加指定寄存器或累加器A的值。 - **INT**:软件中断,用于触发中断服务程序。 - **IOR**和**IOW**:按位或操作,将内容从寄存器写入I/O寄存器或反之。 - **JBC**和**JBS**:位测试指令,根据指定位的设置或清除决定是否跳转。 - **JMP**:无条件跳转,改变程序执行路径。 - **JZ**和**JZA**:根据寄存器或累加器A的值是否为0进行有条件跳转。 - **LCALL**:子程序调用,保存当前地址后跳转到指定地址。 - **LJMP**:无条件长跳转,用于远距离的程序转移。 - **MOV**:数据移动,将数据从一个位置复制到另一个位置。 - **NOP**:空操作指令,不执行任何操作,常用于填充或等待。 - **OR**:按位或操作,合并两个数据源。 - **PAGE**:页切换指令,用于访问不同ROM页面。 - **RET**:从子程序返回,恢复之前的程序计数器。 - **RETI**:中断返回,恢复中断前的状态并继续执行。 - **RETL**:将立即数据返回寄存器,用于加载立即数到寄存器。 这些指令是编程EM78xxx微控制器的基础,掌握它们对于编写高效且可靠的代码至关重要。

请逐行注释下面的代码:class riscv_instr_base_test extends uvm_test; riscv_instr_gen_config cfg; string test_opts; string asm_file_name = "riscv_asm_test"; riscv_asm_program_gen asm_gen; string instr_seq; int start_idx; uvm_coreservice_t coreservice; uvm_factory factory; uvm_component_utils(riscv_instr_base_test) function new(string name="", uvm_component parent=null); super.new(name, parent); void'($value$plusargs("asm_file_name=%0s", asm_file_name)); void'($value$plusargs("start_idx=%0d", start_idx)); endfunction virtual function void build_phase(uvm_phase phase); super.build_phase(phase); coreservice = uvm_coreservice_t::get(); factory = coreservice.get_factory(); uvm_info(gfn, "Create configuration instance", UVM_LOW) cfg = riscv_instr_gen_config::type_id::create("cfg"); uvm_info(gfn, "Create configuration instance...done", UVM_LOW) uvm_config_db#(riscv_instr_gen_config)::set(null, "*", "instr_cfg", cfg); if(cfg.asm_test_suffix != "") asm_file_name = {asm_file_name, ".", cfg.asm_test_suffix}; // Override the default riscv instruction sequence if($value$plusargs("instr_seq=%0s", instr_seq)) begin factory.set_type_override_by_name("riscv_instr_sequence", instr_seq); end if (riscv_instr_pkg::support_debug_mode) begin factory.set_inst_override_by_name("riscv_asm_program_gen", "riscv_debug_rom_gen", {gfn, ".asm_gen.debug_rom"}); end endfunction function void report_phase(uvm_phase phase); uvm_report_server rs; int error_count; rs = uvm_report_server::get_server(); error_count = rs.get_severity_count(UVM_WARNING) + rs.get_severity_count(UVM_ERROR) + rs.get_severity_count(UVM_FATAL); if (error_count == 0) begin uvm_info("", "TEST PASSED", UVM_NONE); end else begin uvm_info("", "TEST FAILED", UVM_NONE); end uvm_info("", "TEST GENERATION DONE", UVM_NONE); super.report_phase(phase); endfunction virtual function void apply_directed_instr(); endfunction task run_phase(uvm_phase phase); int fd; for(int i = 0; i < cfg.num_of_tests; i++) begin string test_name; randomize_cfg(); riscv_instr::create_instr_list(cfg); riscv_csr_instr::create_csr_filter(cfg); asm_gen = riscv_asm_program_gen::type_id::create("asm_gen", , gfn); asm_gen.cfg = cfg; asm_gen.get_directed_instr_stream(); test_name = $sformatf("%0s_%0d.S", asm_file_name, i+start_idx); apply_directed_instr(); uvm_info(gfn, "All directed instruction is applied", UVM_LOW) asm_gen.gen_program(); asm_gen.gen_test_file(test_name); end endtask virtual function void randomize_cfg(); DV_CHECK_RANDOMIZE_FATAL(cfg); uvm_info(`gfn, $sformatf("riscv_instr_gen_config is randomized:\n%0s", cfg.sprint()), UVM_LOW) endfunction endclass

2023-05-24 上传