Remove irq support.
This commit is contained in:
		
							parent
							
								
									2b3f3d3f3d
								
							
						
					
					
						commit
						ef6fb8848f
					
				
							
								
								
									
										4
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										4
									
								
								Makefile
								
								
								
								
							|  | @ -12,7 +12,7 @@ IVERILOG = iverilog$(ICARUS_SUFFIX) | |||
| VVP = vvp$(ICARUS_SUFFIX) | ||||
| 
 | ||||
| TEST_OBJS = $(addsuffix .o,$(basename $(wildcard tests/*.S))) | ||||
| FIRMWARE_OBJS = build/start.o build/irq.o build/print.o build/hello.o build/sieve.o build/multest.o build/stats.o | ||||
| FIRMWARE_OBJS = build/start.o build/print.o build/hello.o build/sieve.o build/multest.o build/stats.o | ||||
| GCC_WARNS  = -Werror -Wall -Wextra -Wshadow -Wundef -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings | ||||
| GCC_WARNS += -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic # -Wconversion | ||||
| TOOLCHAIN_PREFIX = $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)/bin/riscv32-unknown-elf- | ||||
|  | @ -25,7 +25,7 @@ test_verilator: build/testbench_verilator build/firmware.hex build/dhry.hex | |||
| 	cd build && ./testbench_verilator firmware.hex | ||||
| 	cd build && ./testbench_verilator dhry.hex | ||||
| 
 | ||||
| firmware: build/testbench_verilator | ||||
| firmware: build/testbench_verilator build/firmware.hex | ||||
| 	cd build && ./testbench_verilator firmware.hex | ||||
| 
 | ||||
| dhry: build/firmware.hex build/dhry.hex | ||||
|  |  | |||
|  | @ -11,9 +11,6 @@ | |||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| // irq.c
 | ||||
| uint32_t *irq(uint32_t *regs, uint32_t irqs); | ||||
| 
 | ||||
| // print.c
 | ||||
| void print_chr(char ch); | ||||
| void print_str(const char *p); | ||||
|  |  | |||
							
								
								
									
										140
									
								
								firmware/irq.c
								
								
								
								
							
							
						
						
									
										140
									
								
								firmware/irq.c
								
								
								
								
							|  | @ -1,140 +0,0 @@ | |||
| // This is free and unencumbered software released into the public domain.
 | ||||
| //
 | ||||
| // Anyone is free to copy, modify, publish, use, compile, sell, or
 | ||||
| // distribute this software, either in source code form or as a compiled
 | ||||
| // binary, for any purpose, commercial or non-commercial, and by any
 | ||||
| // means.
 | ||||
| 
 | ||||
| #include "firmware.h" | ||||
| 
 | ||||
| uint32_t *irq(uint32_t *regs, uint32_t irqs) | ||||
| { | ||||
| 	static unsigned int ext_irq_4_count = 0; | ||||
| 	static unsigned int ext_irq_5_count = 0; | ||||
| 	static unsigned int timer_irq_count = 0; | ||||
| 
 | ||||
| 	// checking compressed isa q0 reg handling
 | ||||
| 	if ((irqs & 6) != 0) { | ||||
| 		uint32_t pc = (regs[0] & 1) ? regs[0] - 3 : regs[0] - 4; | ||||
| 		uint32_t instr = *(uint16_t*)pc; | ||||
| 
 | ||||
| 		if ((instr & 3) == 3) | ||||
| 			instr = instr | (*(uint16_t*)(pc + 2)) << 16; | ||||
| 
 | ||||
| 		if (((instr & 3) != 3) != (regs[0] & 1)) { | ||||
| 			print_str("Mismatch between q0 LSB and decoded instruction word! q0=0x"); | ||||
| 			print_hex(regs[0], 8); | ||||
| 			print_str(", instr=0x"); | ||||
| 			if ((instr & 3) == 3) | ||||
| 				print_hex(instr, 8); | ||||
| 			else | ||||
| 				print_hex(instr, 4); | ||||
| 			print_str("\n"); | ||||
| 			__asm__ volatile ("ebreak"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if ((irqs & (1<<4)) != 0) { | ||||
| 		ext_irq_4_count++; | ||||
| 		// print_str("[EXT-IRQ-4]");
 | ||||
| 	} | ||||
| 
 | ||||
| 	if ((irqs & (1<<5)) != 0) { | ||||
| 		ext_irq_5_count++; | ||||
| 		// print_str("[EXT-IRQ-5]");
 | ||||
| 	} | ||||
| 
 | ||||
| 	if ((irqs & 1) != 0) { | ||||
| 		timer_irq_count++; | ||||
| 		// print_str("[TIMER-IRQ]");
 | ||||
| 	} | ||||
| 
 | ||||
| 	if ((irqs & 6) != 0) | ||||
| 	{ | ||||
| 		uint32_t pc = (regs[0] & 1) ? regs[0] - 3 : regs[0] - 4; | ||||
| 		uint32_t instr = *(uint16_t*)pc; | ||||
| 
 | ||||
| 		if ((instr & 3) == 3) | ||||
| 			instr = instr | (*(uint16_t*)(pc + 2)) << 16; | ||||
| 
 | ||||
| 		print_str("\n"); | ||||
| 		print_str("------------------------------------------------------------\n"); | ||||
| 
 | ||||
| 		if ((irqs & 2) != 0) { | ||||
| 			if (instr == 0x00100073 || instr == 0x9002) { | ||||
| 				print_str("EBREAK instruction at 0x"); | ||||
| 				print_hex(pc, 8); | ||||
| 				print_str("\n"); | ||||
| 			} else { | ||||
| 				print_str("Illegal Instruction at 0x"); | ||||
| 				print_hex(pc, 8); | ||||
| 				print_str(": 0x"); | ||||
| 				print_hex(instr, ((instr & 3) == 3) ? 8 : 4); | ||||
| 				print_str("\n"); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if ((irqs & 4) != 0) { | ||||
| 			print_str("Bus error in Instruction at 0x"); | ||||
| 			print_hex(pc, 8); | ||||
| 			print_str(": 0x"); | ||||
| 			print_hex(instr, ((instr & 3) == 3) ? 8 : 4); | ||||
| 			print_str("\n"); | ||||
| 		} | ||||
| 
 | ||||
| 		for (int i = 0; i < 8; i++) | ||||
| 		for (int k = 0; k < 4; k++) | ||||
| 		{ | ||||
| 			int r = i + k*8; | ||||
| 
 | ||||
| 			if (r == 0) { | ||||
| 				print_str("pc  "); | ||||
| 			} else | ||||
| 			if (r < 10) { | ||||
| 				print_chr('x'); | ||||
| 				print_chr('0' + r); | ||||
| 				print_chr(' '); | ||||
| 				print_chr(' '); | ||||
| 			} else | ||||
| 			if (r < 20) { | ||||
| 				print_chr('x'); | ||||
| 				print_chr('1'); | ||||
| 				print_chr('0' + r - 10); | ||||
| 				print_chr(' '); | ||||
| 			} else | ||||
| 			if (r < 30) { | ||||
| 				print_chr('x'); | ||||
| 				print_chr('2'); | ||||
| 				print_chr('0' + r - 20); | ||||
| 				print_chr(' '); | ||||
| 			} else { | ||||
| 				print_chr('x'); | ||||
| 				print_chr('3'); | ||||
| 				print_chr('0' + r - 30); | ||||
| 				print_chr(' '); | ||||
| 			} | ||||
| 
 | ||||
| 			print_hex(regs[r], 8); | ||||
| 			print_str(k == 3 ? "\n" : "    "); | ||||
| 		} | ||||
| 
 | ||||
| 		print_str("------------------------------------------------------------\n"); | ||||
| 
 | ||||
| 		print_str("Number of fast external IRQs counted: "); | ||||
| 		print_dec(ext_irq_4_count); | ||||
| 		print_str("\n"); | ||||
| 
 | ||||
| 		print_str("Number of slow external IRQs counted: "); | ||||
| 		print_dec(ext_irq_5_count); | ||||
| 		print_str("\n"); | ||||
| 
 | ||||
| 		print_str("Number of timer IRQs counted: "); | ||||
| 		print_dec(timer_irq_count); | ||||
| 		print_str("\n"); | ||||
| 
 | ||||
| 		__asm__ volatile ("ebreak"); | ||||
| 	} | ||||
| 
 | ||||
| 	return regs; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										309
									
								
								firmware/start.S
								
								
								
								
							
							
						
						
									
										309
									
								
								firmware/start.S
								
								
								
								
							|  | @ -5,26 +5,14 @@ | |||
| // binary, for any purpose, commercial or non-commercial, and by any | ||||
| // means. | ||||
| 
 | ||||
| #define ENABLE_QREGS | ||||
| #define ENABLE_HELLO | ||||
| #define ENABLE_RVTST | ||||
| #define ENABLE_SIEVE | ||||
| #define ENABLE_MULTST | ||||
| #define ENABLE_STATS | ||||
| 
 | ||||
| #ifndef ENABLE_QREGS | ||||
| #  undef ENABLE_RVTST | ||||
| #endif | ||||
| 
 | ||||
| // Only save registers in IRQ wrapper that are to be saved by the caller in | ||||
| // the RISC-V ABI, with the excpetion of the stack pointer. The IRQ handler | ||||
| // will save the rest if necessary. I.e. skip x3, x4, x8, x9, and x18-x27. | ||||
| #undef ENABLE_FASTIRQ | ||||
| 
 | ||||
| #include "custom_ops.S" | ||||
| 
 | ||||
| 	.section .text | ||||
| 	.global irq
 | ||||
| 	.global hello
 | ||||
| 	.global sieve
 | ||||
| 	.global multest
 | ||||
|  | @ -39,305 +27,8 @@ | |||
| 	.global stats
 | ||||
| 
 | ||||
| reset_vec: | ||||
| 	// no more than 16 bytes here ! | ||||
| 	picorv32_waitirq_insn(zero) | ||||
| 	picorv32_maskirq_insn(zero, zero) | ||||
| 	j start | ||||
| 
 | ||||
| 
 | ||||
| /* Interrupt handler | ||||
|  **********************************/ | ||||
| 
 | ||||
| .balign 16
 | ||||
| irq_vec: | ||||
| 	/* save registers */ | ||||
| 
 | ||||
| #ifdef ENABLE_QREGS | ||||
| 
 | ||||
| 	picorv32_setq_insn(q2, x1) | ||||
| 	picorv32_setq_insn(q3, x2) | ||||
| 
 | ||||
| 	lui x1, %hi(irq_regs) | ||||
| 	addi x1, x1, %lo(irq_regs) | ||||
| 
 | ||||
| 	picorv32_getq_insn(x2, q0) | ||||
| 	sw x2,   0*4(x1) | ||||
| 
 | ||||
| 	picorv32_getq_insn(x2, q2) | ||||
| 	sw x2,   1*4(x1) | ||||
| 
 | ||||
| 	picorv32_getq_insn(x2, q3) | ||||
| 	sw x2,   2*4(x1) | ||||
| 
 | ||||
| #ifdef ENABLE_FASTIRQ | ||||
| 	sw x5,   5*4(x1) | ||||
| 	sw x6,   6*4(x1) | ||||
| 	sw x7,   7*4(x1) | ||||
| 	sw x10, 10*4(x1) | ||||
| 	sw x11, 11*4(x1) | ||||
| 	sw x12, 12*4(x1) | ||||
| 	sw x13, 13*4(x1) | ||||
| 	sw x14, 14*4(x1) | ||||
| 	sw x15, 15*4(x1) | ||||
| 	sw x16, 16*4(x1) | ||||
| 	sw x17, 17*4(x1) | ||||
| 	sw x28, 28*4(x1) | ||||
| 	sw x29, 29*4(x1) | ||||
| 	sw x30, 30*4(x1) | ||||
| 	sw x31, 31*4(x1) | ||||
| #else | ||||
| 	sw x3,   3*4(x1) | ||||
| 	sw x4,   4*4(x1) | ||||
| 	sw x5,   5*4(x1) | ||||
| 	sw x6,   6*4(x1) | ||||
| 	sw x7,   7*4(x1) | ||||
| 	sw x8,   8*4(x1) | ||||
| 	sw x9,   9*4(x1) | ||||
| 	sw x10, 10*4(x1) | ||||
| 	sw x11, 11*4(x1) | ||||
| 	sw x12, 12*4(x1) | ||||
| 	sw x13, 13*4(x1) | ||||
| 	sw x14, 14*4(x1) | ||||
| 	sw x15, 15*4(x1) | ||||
| 	sw x16, 16*4(x1) | ||||
| 	sw x17, 17*4(x1) | ||||
| 	sw x18, 18*4(x1) | ||||
| 	sw x19, 19*4(x1) | ||||
| 	sw x20, 20*4(x1) | ||||
| 	sw x21, 21*4(x1) | ||||
| 	sw x22, 22*4(x1) | ||||
| 	sw x23, 23*4(x1) | ||||
| 	sw x24, 24*4(x1) | ||||
| 	sw x25, 25*4(x1) | ||||
| 	sw x26, 26*4(x1) | ||||
| 	sw x27, 27*4(x1) | ||||
| 	sw x28, 28*4(x1) | ||||
| 	sw x29, 29*4(x1) | ||||
| 	sw x30, 30*4(x1) | ||||
| 	sw x31, 31*4(x1) | ||||
| #endif | ||||
| 
 | ||||
| #else // ENABLE_QREGS | ||||
| 
 | ||||
| #ifdef ENABLE_FASTIRQ | ||||
| 	sw gp,   0*4+0x200(zero) | ||||
| 	sw x1,   1*4+0x200(zero) | ||||
| 	sw x2,   2*4+0x200(zero) | ||||
| 	sw x5,   5*4+0x200(zero) | ||||
| 	sw x6,   6*4+0x200(zero) | ||||
| 	sw x7,   7*4+0x200(zero) | ||||
| 	sw x10, 10*4+0x200(zero) | ||||
| 	sw x11, 11*4+0x200(zero) | ||||
| 	sw x12, 12*4+0x200(zero) | ||||
| 	sw x13, 13*4+0x200(zero) | ||||
| 	sw x14, 14*4+0x200(zero) | ||||
| 	sw x15, 15*4+0x200(zero) | ||||
| 	sw x16, 16*4+0x200(zero) | ||||
| 	sw x17, 17*4+0x200(zero) | ||||
| 	sw x28, 28*4+0x200(zero) | ||||
| 	sw x29, 29*4+0x200(zero) | ||||
| 	sw x30, 30*4+0x200(zero) | ||||
| 	sw x31, 31*4+0x200(zero) | ||||
| #else | ||||
| 	sw gp,   0*4+0x200(zero) | ||||
| 	sw x1,   1*4+0x200(zero) | ||||
| 	sw x2,   2*4+0x200(zero) | ||||
| 	sw x3,   3*4+0x200(zero) | ||||
| 	sw x4,   4*4+0x200(zero) | ||||
| 	sw x5,   5*4+0x200(zero) | ||||
| 	sw x6,   6*4+0x200(zero) | ||||
| 	sw x7,   7*4+0x200(zero) | ||||
| 	sw x8,   8*4+0x200(zero) | ||||
| 	sw x9,   9*4+0x200(zero) | ||||
| 	sw x10, 10*4+0x200(zero) | ||||
| 	sw x11, 11*4+0x200(zero) | ||||
| 	sw x12, 12*4+0x200(zero) | ||||
| 	sw x13, 13*4+0x200(zero) | ||||
| 	sw x14, 14*4+0x200(zero) | ||||
| 	sw x15, 15*4+0x200(zero) | ||||
| 	sw x16, 16*4+0x200(zero) | ||||
| 	sw x17, 17*4+0x200(zero) | ||||
| 	sw x18, 18*4+0x200(zero) | ||||
| 	sw x19, 19*4+0x200(zero) | ||||
| 	sw x20, 20*4+0x200(zero) | ||||
| 	sw x21, 21*4+0x200(zero) | ||||
| 	sw x22, 22*4+0x200(zero) | ||||
| 	sw x23, 23*4+0x200(zero) | ||||
| 	sw x24, 24*4+0x200(zero) | ||||
| 	sw x25, 25*4+0x200(zero) | ||||
| 	sw x26, 26*4+0x200(zero) | ||||
| 	sw x27, 27*4+0x200(zero) | ||||
| 	sw x28, 28*4+0x200(zero) | ||||
| 	sw x29, 29*4+0x200(zero) | ||||
| 	sw x30, 30*4+0x200(zero) | ||||
| 	sw x31, 31*4+0x200(zero) | ||||
| #endif | ||||
| 
 | ||||
| #endif // ENABLE_QREGS | ||||
| 
 | ||||
| 	/* call interrupt handler C function */ | ||||
| 
 | ||||
| 	lui sp, %hi(irq_stack) | ||||
| 	addi sp, sp, %lo(irq_stack) | ||||
| 
 | ||||
| 	// arg0 = address of regs | ||||
| 	lui a0, %hi(irq_regs) | ||||
| 	addi a0, a0, %lo(irq_regs) | ||||
| 
 | ||||
| 	// arg1 = interrupt type | ||||
| #ifdef ENABLE_QREGS | ||||
| 	picorv32_getq_insn(a1, q1) | ||||
| #else | ||||
| 	addi a1, tp, 0 | ||||
| #endif | ||||
| 
 | ||||
| 	// call to C function | ||||
| 	jal ra, irq | ||||
| 
 | ||||
| 	/* restore registers */ | ||||
| 
 | ||||
| #ifdef ENABLE_QREGS | ||||
| 
 | ||||
| 	// new irq_regs address returned from C code in a0 | ||||
| 	addi x1, a0, 0 | ||||
| 
 | ||||
| 	lw x2,   0*4(x1) | ||||
| 	picorv32_setq_insn(q0, x2) | ||||
| 
 | ||||
| 	lw x2,   1*4(x1) | ||||
| 	picorv32_setq_insn(q1, x2) | ||||
| 
 | ||||
| 	lw x2,   2*4(x1) | ||||
| 	picorv32_setq_insn(q2, x2) | ||||
| 
 | ||||
| #ifdef ENABLE_FASTIRQ | ||||
| 	lw x5,   5*4(x1) | ||||
| 	lw x6,   6*4(x1) | ||||
| 	lw x7,   7*4(x1) | ||||
| 	lw x10, 10*4(x1) | ||||
| 	lw x11, 11*4(x1) | ||||
| 	lw x12, 12*4(x1) | ||||
| 	lw x13, 13*4(x1) | ||||
| 	lw x14, 14*4(x1) | ||||
| 	lw x15, 15*4(x1) | ||||
| 	lw x16, 16*4(x1) | ||||
| 	lw x17, 17*4(x1) | ||||
| 	lw x28, 28*4(x1) | ||||
| 	lw x29, 29*4(x1) | ||||
| 	lw x30, 30*4(x1) | ||||
| 	lw x31, 31*4(x1) | ||||
| #else | ||||
| 	lw x3,   3*4(x1) | ||||
| 	lw x4,   4*4(x1) | ||||
| 	lw x5,   5*4(x1) | ||||
| 	lw x6,   6*4(x1) | ||||
| 	lw x7,   7*4(x1) | ||||
| 	lw x8,   8*4(x1) | ||||
| 	lw x9,   9*4(x1) | ||||
| 	lw x10, 10*4(x1) | ||||
| 	lw x11, 11*4(x1) | ||||
| 	lw x12, 12*4(x1) | ||||
| 	lw x13, 13*4(x1) | ||||
| 	lw x14, 14*4(x1) | ||||
| 	lw x15, 15*4(x1) | ||||
| 	lw x16, 16*4(x1) | ||||
| 	lw x17, 17*4(x1) | ||||
| 	lw x18, 18*4(x1) | ||||
| 	lw x19, 19*4(x1) | ||||
| 	lw x20, 20*4(x1) | ||||
| 	lw x21, 21*4(x1) | ||||
| 	lw x22, 22*4(x1) | ||||
| 	lw x23, 23*4(x1) | ||||
| 	lw x24, 24*4(x1) | ||||
| 	lw x25, 25*4(x1) | ||||
| 	lw x26, 26*4(x1) | ||||
| 	lw x27, 27*4(x1) | ||||
| 	lw x28, 28*4(x1) | ||||
| 	lw x29, 29*4(x1) | ||||
| 	lw x30, 30*4(x1) | ||||
| 	lw x31, 31*4(x1) | ||||
| #endif | ||||
| 
 | ||||
| 	picorv32_getq_insn(x1, q1) | ||||
| 	picorv32_getq_insn(x2, q2) | ||||
| 
 | ||||
| #else // ENABLE_QREGS | ||||
| 
 | ||||
| 	// new irq_regs address returned from C code in a0 | ||||
| 	addi a1, zero, 0x200 | ||||
| 	beq a0, a1, 1f | ||||
| 	ebreak | ||||
| 1: | ||||
| 
 | ||||
| #ifdef ENABLE_FASTIRQ | ||||
| 	lw gp,   0*4+0x200(zero) | ||||
| 	lw x1,   1*4+0x200(zero) | ||||
| 	lw x2,   2*4+0x200(zero) | ||||
| 	lw x5,   5*4+0x200(zero) | ||||
| 	lw x6,   6*4+0x200(zero) | ||||
| 	lw x7,   7*4+0x200(zero) | ||||
| 	lw x10, 10*4+0x200(zero) | ||||
| 	lw x11, 11*4+0x200(zero) | ||||
| 	lw x12, 12*4+0x200(zero) | ||||
| 	lw x13, 13*4+0x200(zero) | ||||
| 	lw x14, 14*4+0x200(zero) | ||||
| 	lw x15, 15*4+0x200(zero) | ||||
| 	lw x16, 16*4+0x200(zero) | ||||
| 	lw x17, 17*4+0x200(zero) | ||||
| 	lw x28, 28*4+0x200(zero) | ||||
| 	lw x29, 29*4+0x200(zero) | ||||
| 	lw x30, 30*4+0x200(zero) | ||||
| 	lw x31, 31*4+0x200(zero) | ||||
| #else | ||||
| 	lw gp,   0*4+0x200(zero) | ||||
| 	lw x1,   1*4+0x200(zero) | ||||
| 	lw x2,   2*4+0x200(zero) | ||||
| 	// do not restore x3 (gp) | ||||
| 	lw x4,   4*4+0x200(zero) | ||||
| 	lw x5,   5*4+0x200(zero) | ||||
| 	lw x6,   6*4+0x200(zero) | ||||
| 	lw x7,   7*4+0x200(zero) | ||||
| 	lw x8,   8*4+0x200(zero) | ||||
| 	lw x9,   9*4+0x200(zero) | ||||
| 	lw x10, 10*4+0x200(zero) | ||||
| 	lw x11, 11*4+0x200(zero) | ||||
| 	lw x12, 12*4+0x200(zero) | ||||
| 	lw x13, 13*4+0x200(zero) | ||||
| 	lw x14, 14*4+0x200(zero) | ||||
| 	lw x15, 15*4+0x200(zero) | ||||
| 	lw x16, 16*4+0x200(zero) | ||||
| 	lw x17, 17*4+0x200(zero) | ||||
| 	lw x18, 18*4+0x200(zero) | ||||
| 	lw x19, 19*4+0x200(zero) | ||||
| 	lw x20, 20*4+0x200(zero) | ||||
| 	lw x21, 21*4+0x200(zero) | ||||
| 	lw x22, 22*4+0x200(zero) | ||||
| 	lw x23, 23*4+0x200(zero) | ||||
| 	lw x24, 24*4+0x200(zero) | ||||
| 	lw x25, 25*4+0x200(zero) | ||||
| 	lw x26, 26*4+0x200(zero) | ||||
| 	lw x27, 27*4+0x200(zero) | ||||
| 	lw x28, 28*4+0x200(zero) | ||||
| 	lw x29, 29*4+0x200(zero) | ||||
| 	lw x30, 30*4+0x200(zero) | ||||
| 	lw x31, 31*4+0x200(zero) | ||||
| #endif | ||||
| 
 | ||||
| #endif // ENABLE_QREGS | ||||
| 
 | ||||
| 	picorv32_retirq_insn() | ||||
| 
 | ||||
| .balign 0x200
 | ||||
| irq_regs: | ||||
| 	// registers are saved to this memory region during interrupt handling | ||||
| 	// the program counter is saved as register 0 | ||||
| 	.fill 32,4 | ||||
| 
 | ||||
| 	// stack for the interrupt handler | ||||
| 	.fill 128,4 | ||||
| irq_stack: | ||||
| 
 | ||||
| 
 | ||||
| /* Main program | ||||
|  **********************************/ | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										191
									
								
								picorv32.v
								
								
								
								
							
							
						
						
									
										191
									
								
								picorv32.v
								
								
								
								
							|  | @ -24,6 +24,7 @@ | |||
| 
 | ||||
| `timescale 1 ns / 1 ps | ||||
| // `default_nettype none | ||||
| // `define DEBUG | ||||
| 
 | ||||
| `ifdef DEBUG | ||||
| `define debug(debug_command) debug_command | ||||
|  | @ -40,10 +41,7 @@ | |||
| 
 | ||||
| module picorv32 #( | ||||
|     parameter [0:0] ENABLE_TRACE = 0, | ||||
|     parameter [31:0] MASKED_IRQ = 32'h0000_0000, | ||||
|     parameter [31:0] LATCHED_IRQ = 32'hffff_ffff, | ||||
|     parameter [31:0] PROGADDR_RESET = 32'h0000_0000, | ||||
|     parameter [31:0] PROGADDR_IRQ = 32'h0000_0010, | ||||
|     parameter [31:0] STACKADDR = 32'hffff_ffff | ||||
| ) ( | ||||
|     input clk, | ||||
|  | @ -76,10 +74,6 @@ module picorv32 #( | |||
|     input             pcpi_wait, | ||||
|     input             pcpi_ready, | ||||
| 
 | ||||
|     // IRQ Interface | ||||
|     input      [31:0] irq, | ||||
|     output reg [31:0] eoi, | ||||
| 
 | ||||
|     // Trace Interface | ||||
|     output reg        trace_valid, | ||||
|     output reg [35:0] trace_data, | ||||
|  | @ -90,16 +84,11 @@ module picorv32 #( | |||
|     output reg [31:0] dbg_insn_addr, | ||||
|     output reg [63:0] dbg_ascii_instr | ||||
| ); | ||||
|   localparam integer irq_timer = 0; | ||||
|   localparam integer irq_ebreak = 1; | ||||
|   localparam integer irq_buserror = 2; | ||||
| 
 | ||||
|   localparam integer irqregs_offset = 32; | ||||
|   localparam integer regfile_size = 32 + 4; | ||||
|   localparam integer regindex_bits = 5 + 1; | ||||
|   localparam integer regfile_size = 32; | ||||
|   localparam integer regindex_bits = 5; | ||||
|   localparam [35:0] TRACE_BRANCH = {4'b0001, 32'b0}; | ||||
|   localparam [35:0] TRACE_ADDR = {4'b0010, 32'b0}; | ||||
|   localparam [35:0] TRACE_IRQ = {4'b1000, 32'b0}; | ||||
| 
 | ||||
|   reg [63:0] count_cycle, count_instr; | ||||
|   reg [31:0] reg_pc, reg_next_pc, reg_op1, reg_op2, reg_out; | ||||
|  | @ -120,12 +109,6 @@ module picorv32 #( | |||
| 
 | ||||
|   wire [31:0] next_pc; | ||||
| 
 | ||||
|   reg irq_delay; | ||||
|   reg irq_active; | ||||
|   reg [31:0] irq_mask; | ||||
|   reg [31:0] irq_pending; | ||||
|   reg [31:0] timer; | ||||
| 
 | ||||
|   task empty_statement; | ||||
|     // This task is used by the `assert directive in non-formal mode to | ||||
|     // avoid empty statement (which are unsupported by plain Verilog syntax). | ||||
|  | @ -362,7 +345,6 @@ module picorv32 #( | |||
|   reg instr_add, instr_sub, instr_sll, instr_slt, instr_sltu; | ||||
|   reg instr_xor, instr_srl, instr_sra, instr_or, instr_and; | ||||
|   reg instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh, instr_ecall_ebreak; | ||||
|   reg instr_getq, instr_setq, instr_retirq, instr_maskirq, instr_waitirq, instr_timer; | ||||
|   wire instr_trap; | ||||
| 
 | ||||
|   reg [regindex_bits-1:0] decoded_rd, decoded_rs1, decoded_rs2; | ||||
|  | @ -392,8 +374,7 @@ module picorv32 #( | |||
| 			instr_lb, instr_lh, instr_lw, instr_lbu, instr_lhu, instr_sb, instr_sh, instr_sw, | ||||
| 			instr_addi, instr_slti, instr_sltiu, instr_xori, instr_ori, instr_andi, instr_slli, instr_srli, instr_srai, | ||||
| 			instr_add, instr_sub, instr_sll, instr_slt, instr_sltu, instr_xor, instr_srl, instr_sra, instr_or, instr_and, | ||||
| 			instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh, | ||||
| 			instr_getq, instr_setq, instr_retirq, instr_maskirq, instr_waitirq, instr_timer}; | ||||
| 			instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh}; | ||||
| 
 | ||||
|   wire is_rdcycle_rdcycleh_rdinstr_rdinstrh; | ||||
|   assign is_rdcycle_rdcycleh_rdinstr_rdinstrh = |{instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh}; | ||||
|  | @ -461,12 +442,6 @@ module picorv32 #( | |||
|     if (instr_rdinstr) new_ascii_instr = "rdinstr"; | ||||
|     if (instr_rdinstrh) new_ascii_instr = "rdinstrh"; | ||||
| 
 | ||||
|     if (instr_getq) new_ascii_instr = "getq"; | ||||
|     if (instr_setq) new_ascii_instr = "setq"; | ||||
|     if (instr_retirq) new_ascii_instr = "retirq"; | ||||
|     if (instr_maskirq) new_ascii_instr = "maskirq"; | ||||
|     if (instr_waitirq) new_ascii_instr = "waitirq"; | ||||
|     if (instr_timer) new_ascii_instr = "timer"; | ||||
|   end | ||||
| 
 | ||||
|   reg [63:0] q_ascii_instr; | ||||
|  | @ -554,8 +529,6 @@ module picorv32 #( | |||
|       instr_auipc <= mem_rdata_latched[6:0] == 7'b0010111; | ||||
|       instr_jal <= mem_rdata_latched[6:0] == 7'b1101111; | ||||
|       instr_jalr <= mem_rdata_latched[6:0] == 7'b1100111 && mem_rdata_latched[14:12] == 3'b000; | ||||
|       instr_retirq  <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010; | ||||
|       instr_waitirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000100; | ||||
| 
 | ||||
|       is_beq_bne_blt_bge_bltu_bgeu <= mem_rdata_latched[6:0] == 7'b1100011; | ||||
|       is_lb_lh_lw_lbu_lhu <= mem_rdata_latched[6:0] == 7'b0000011; | ||||
|  | @ -570,12 +543,6 @@ module picorv32 #( | |||
|       decoded_rd <= mem_rdata_latched[11:7]; | ||||
|       decoded_rs1 <= mem_rdata_latched[19:15]; | ||||
|       decoded_rs2 <= mem_rdata_latched[24:20]; | ||||
| 
 | ||||
|       if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000000) | ||||
|         decoded_rs1[regindex_bits-1] <= 1;  // instr_getq | ||||
| 
 | ||||
|       if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010) | ||||
|         decoded_rs1 <= irqregs_offset;  // instr_retirq | ||||
|     end | ||||
| 
 | ||||
|     if (decoder_trigger && !decoder_pseudo_trigger) begin | ||||
|  | @ -629,11 +596,6 @@ module picorv32 #( | |||
| 
 | ||||
|       instr_ecall_ebreak <= (mem_rdata_q[6:0] == 7'b1110011 && !mem_rdata_q[31:21] && !mem_rdata_q[19:7]); | ||||
| 
 | ||||
|       instr_getq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000000; | ||||
|       instr_setq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000001; | ||||
|       instr_maskirq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000011; | ||||
|       instr_timer <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000101; | ||||
| 
 | ||||
|       is_slli_srli_srai <= is_alu_reg_imm && |{ | ||||
| 				mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000, | ||||
| 				mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0000000, | ||||
|  | @ -717,7 +679,6 @@ module picorv32 #( | |||
|   localparam cpu_state_ldmem = 8'b00000001; | ||||
| 
 | ||||
|   reg [7:0] cpu_state; | ||||
|   reg [1:0] irq_state; | ||||
| 
 | ||||
|   always @* begin | ||||
|     dbg_ascii_state = ""; | ||||
|  | @ -750,9 +711,6 @@ module picorv32 #( | |||
|   reg [3:0] pcpi_timeout_counter; | ||||
|   reg pcpi_timeout; | ||||
| 
 | ||||
|   reg [31:0] next_irq_pending; | ||||
|   reg do_waitirq; | ||||
| 
 | ||||
|   reg [31:0] alu_out, alu_out_q; | ||||
|   reg alu_out_0, alu_out_0_q; | ||||
| 
 | ||||
|  | @ -815,14 +773,6 @@ module picorv32 #( | |||
|           cpuregs_wrdata = latched_stalu ? alu_out_q : reg_out; | ||||
|           cpuregs_write  = 1; | ||||
|         end | ||||
|         irq_state[0]: begin | ||||
|           cpuregs_wrdata = reg_next_pc; | ||||
|           cpuregs_write  = 1; | ||||
|         end | ||||
|         irq_state[1]: begin | ||||
|           cpuregs_wrdata = irq_pending & ~irq_mask; | ||||
|           cpuregs_write  = 1; | ||||
|         end | ||||
|       endcase | ||||
|     end | ||||
|   end | ||||
|  | @ -851,7 +801,7 @@ module picorv32 #( | |||
|     cpuregs_rs2 = decoded_rs2 ? cpuregs_rdata2 : 0; | ||||
|   end | ||||
| 
 | ||||
|   assign launch_next_insn = cpu_state == cpu_state_fetch && decoder_trigger && (irq_delay || irq_active || !(irq_pending & ~irq_mask)); | ||||
|   assign launch_next_insn = cpu_state == cpu_state_fetch && decoder_trigger; | ||||
| 
 | ||||
|   always @(posedge clk) begin | ||||
|     trap <= 0; | ||||
|  | @ -876,17 +826,11 @@ module picorv32 #( | |||
|     end else pcpi_timeout_counter <= ~0; | ||||
|     pcpi_timeout <= !pcpi_timeout_counter; | ||||
|     count_cycle <= resetn ? count_cycle + 1 : 0; | ||||
|     next_irq_pending = irq_pending & LATCHED_IRQ; | ||||
| 
 | ||||
|     if (timer) begin | ||||
|       timer <= timer - 1; | ||||
|     end | ||||
| 
 | ||||
|     decoder_trigger <= mem_do_rinst && mem_done; | ||||
|     decoder_trigger_q <= decoder_trigger; | ||||
|     decoder_pseudo_trigger <= 0; | ||||
|     decoder_pseudo_trigger_q <= decoder_pseudo_trigger; | ||||
|     do_waitirq <= 0; | ||||
| 
 | ||||
|     trace_valid <= 0; | ||||
| 
 | ||||
|  | @ -905,13 +849,6 @@ module picorv32 #( | |||
|       latched_is_lb <= 0; | ||||
|       pcpi_valid <= 0; | ||||
|       pcpi_timeout <= 0; | ||||
|       irq_active <= 0; | ||||
|       irq_delay <= 0; | ||||
|       irq_mask <= ~0; | ||||
|       next_irq_pending = 0; | ||||
|       irq_state <= 0; | ||||
|       eoi <= 0; | ||||
|       timer <= 0; | ||||
|       if (~STACKADDR) begin | ||||
|         latched_store <= 1; | ||||
|         latched_rd <= 2; | ||||
|  | @ -925,7 +862,7 @@ module picorv32 #( | |||
|         end | ||||
| 
 | ||||
|         cpu_state_fetch: begin | ||||
|           mem_do_rinst <= !decoder_trigger && !do_waitirq; | ||||
|           mem_do_rinst <= !decoder_trigger; | ||||
|           mem_wordsize <= 0; | ||||
| 
 | ||||
|           current_pc = reg_next_pc; | ||||
|  | @ -941,23 +878,13 @@ module picorv32 #( | |||
|               `debug($display("ST_RD:  %2d 0x%08x", latched_rd, latched_stalu ? alu_out_q : reg_out | ||||
|                      );) | ||||
|             end | ||||
|             irq_state[0]: begin | ||||
|               current_pc = PROGADDR_IRQ; | ||||
|               irq_active   <= 1; | ||||
|               mem_do_rinst <= 1; | ||||
|             end | ||||
|             irq_state[1]: begin | ||||
|               eoi <= irq_pending & ~irq_mask; | ||||
|               next_irq_pending = next_irq_pending & irq_mask; | ||||
|             end | ||||
|           endcase | ||||
| 
 | ||||
|           if (ENABLE_TRACE && latched_trace) begin | ||||
|             latched_trace <= 0; | ||||
|             trace_valid   <= 1; | ||||
|             if (latched_branch) | ||||
|               trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_BRANCH | (current_pc & 32'hfffffffe); | ||||
|             else trace_data <= (irq_active ? TRACE_IRQ : 0) | (latched_stalu ? alu_out_q : reg_out); | ||||
|             if (latched_branch) trace_data <= TRACE_BRANCH | (current_pc & 32'hfffffffe); | ||||
|             else trace_data <= latched_stalu ? alu_out_q : reg_out; | ||||
|           end | ||||
| 
 | ||||
|           reg_pc <= current_pc; | ||||
|  | @ -971,19 +898,8 @@ module picorv32 #( | |||
|           latched_is_lb <= 0; | ||||
|           latched_rd <= decoded_rd; | ||||
| 
 | ||||
|           if (((decoder_trigger && !irq_active && !irq_delay && |(irq_pending & ~irq_mask)) || irq_state)) begin | ||||
|             irq_state  <= irq_state == 2'b00 ? 2'b01 : irq_state == 2'b01 ? 2'b10 : 2'b00; | ||||
|             latched_rd <= irqregs_offset | irq_state[0]; | ||||
|           end else if ((decoder_trigger || do_waitirq) && instr_waitirq) begin | ||||
|             if (irq_pending) begin | ||||
|               latched_store <= 1; | ||||
|               reg_out <= irq_pending; | ||||
|               reg_next_pc <= current_pc + 4; | ||||
|               mem_do_rinst <= 1; | ||||
|             end else do_waitirq <= 1; | ||||
|           end else if (decoder_trigger) begin | ||||
|           if (decoder_trigger) begin | ||||
|             `debug($display("-- %-0t", $time);) | ||||
|             irq_delay   <= irq_active; | ||||
|             reg_next_pc <= current_pc + 4; | ||||
|             if (ENABLE_TRACE) latched_trace <= 1; | ||||
|             count_instr <= count_instr + 1; | ||||
|  | @ -993,7 +909,7 @@ module picorv32 #( | |||
|               latched_branch <= 1; | ||||
|             end else begin | ||||
|               mem_do_rinst <= 0; | ||||
|               mem_do_prefetch <= !instr_jalr && !instr_retirq; | ||||
|               mem_do_prefetch <= !instr_jalr; | ||||
|               cpu_state <= cpu_state_ld_rs1; | ||||
|             end | ||||
|           end | ||||
|  | @ -1025,10 +941,7 @@ module picorv32 #( | |||
|               end else if (pcpi_timeout || instr_ecall_ebreak) begin | ||||
|                 pcpi_valid <= 0; | ||||
|                 `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);) | ||||
|                 if (!irq_mask[irq_ebreak] && !irq_active) begin | ||||
|                   next_irq_pending[irq_ebreak] = 1; | ||||
|                   cpu_state <= cpu_state_fetch; | ||||
|                 end else cpu_state <= cpu_state_trap; | ||||
|                 cpu_state <= cpu_state_trap; | ||||
|               end | ||||
|             end | ||||
|             is_rdcycle_rdcycleh_rdinstr_rdinstrh: begin | ||||
|  | @ -1048,52 +961,6 @@ module picorv32 #( | |||
|               mem_do_rinst <= mem_do_prefetch; | ||||
|               cpu_state <= cpu_state_exec; | ||||
|             end | ||||
|             instr_getq: begin | ||||
|               `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) | ||||
|               reg_out <= cpuregs_rs1; | ||||
|               dbg_rs1val <= cpuregs_rs1; | ||||
|               dbg_rs1val_valid <= 1; | ||||
|               latched_store <= 1; | ||||
|               cpu_state <= cpu_state_fetch; | ||||
|             end | ||||
|             instr_setq: begin | ||||
|               `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) | ||||
|               reg_out <= cpuregs_rs1; | ||||
|               dbg_rs1val <= cpuregs_rs1; | ||||
|               dbg_rs1val_valid <= 1; | ||||
|               latched_rd <= latched_rd | irqregs_offset; | ||||
|               latched_store <= 1; | ||||
|               cpu_state <= cpu_state_fetch; | ||||
|             end | ||||
|             instr_retirq: begin | ||||
|               eoi <= 0; | ||||
|               irq_active <= 0; | ||||
|               latched_branch <= 1; | ||||
|               latched_store <= 1; | ||||
|               `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) | ||||
|               reg_out <= cpuregs_rs1 & 32'hfffffffe; | ||||
|               dbg_rs1val <= cpuregs_rs1; | ||||
|               dbg_rs1val_valid <= 1; | ||||
|               cpu_state <= cpu_state_fetch; | ||||
|             end | ||||
|             instr_maskirq: begin | ||||
|               latched_store <= 1; | ||||
|               reg_out <= irq_mask; | ||||
|               `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) | ||||
|               irq_mask <= cpuregs_rs1 | MASKED_IRQ; | ||||
|               dbg_rs1val <= cpuregs_rs1; | ||||
|               dbg_rs1val_valid <= 1; | ||||
|               cpu_state <= cpu_state_fetch; | ||||
|             end | ||||
|             instr_timer: begin | ||||
|               latched_store <= 1; | ||||
|               reg_out <= timer; | ||||
|               `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) | ||||
|               timer <= cpuregs_rs1; | ||||
|               dbg_rs1val <= cpuregs_rs1; | ||||
|               dbg_rs1val_valid <= 1; | ||||
|               cpu_state <= cpu_state_fetch; | ||||
|             end | ||||
|             is_lb_lh_lw_lbu_lhu && !instr_trap: begin | ||||
|               `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) | ||||
|               reg_op1 <= cpuregs_rs1; | ||||
|  | @ -1167,10 +1034,7 @@ module picorv32 #( | |||
|               end else if (pcpi_timeout || instr_ecall_ebreak) begin | ||||
|                 pcpi_valid <= 0; | ||||
|                 `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);) | ||||
|                 if (!irq_mask[irq_ebreak] && !irq_active) begin | ||||
|                   next_irq_pending[irq_ebreak] = 1; | ||||
|                   cpu_state <= cpu_state_fetch; | ||||
|                 end else cpu_state <= cpu_state_trap; | ||||
|                 cpu_state <= cpu_state_trap; | ||||
|               end | ||||
|             end | ||||
|             is_sb_sh_sw: begin | ||||
|  | @ -1205,7 +1069,6 @@ module picorv32 #( | |||
|             cpu_state <= cpu_state_fetch; | ||||
|           end | ||||
|         end | ||||
| 
 | ||||
|         cpu_state_shift: begin | ||||
|           latched_store <= 1; | ||||
|           if (reg_sh == 0) begin | ||||
|  | @ -1243,7 +1106,7 @@ module picorv32 #( | |||
|               endcase | ||||
|               if (ENABLE_TRACE) begin | ||||
|                 trace_valid <= 1; | ||||
|                 trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_ADDR | ((reg_op1 + decoded_imm) & 32'hffffffff); | ||||
|                 trace_data  <= TRACE_ADDR | ((reg_op1 + decoded_imm) & 32'hffffffff); | ||||
|               end | ||||
|               reg_op1 <= reg_op1 + decoded_imm; | ||||
|               set_mem_do_wdata = 1; | ||||
|  | @ -1271,7 +1134,7 @@ module picorv32 #( | |||
|               latched_is_lb <= instr_lb; | ||||
|               if (ENABLE_TRACE) begin | ||||
|                 trace_valid <= 1; | ||||
|                 trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_ADDR | ((reg_op1 + decoded_imm) & 32'hffffffff); | ||||
|                 trace_data  <= TRACE_ADDR | ((reg_op1 + decoded_imm) & 32'hffffffff); | ||||
|               end | ||||
|               reg_op1 <= reg_op1 + decoded_imm; | ||||
|               set_mem_do_rdata = 1; | ||||
|  | @ -1291,28 +1154,19 @@ module picorv32 #( | |||
|         end | ||||
|       endcase | ||||
| 
 | ||||
|     next_irq_pending = next_irq_pending | irq; | ||||
|     if (timer) if (timer - 1 == 0) next_irq_pending[irq_timer] = 1; | ||||
| 
 | ||||
|     if (resetn && (mem_do_rdata || mem_do_wdata)) begin | ||||
|       if (mem_wordsize == 0 && reg_op1[1:0] != 0) begin | ||||
|         `debug($display("MISALIGNED WORD: 0x%08x", reg_op1);) | ||||
|         if (!irq_mask[irq_buserror] && !irq_active) begin | ||||
|           next_irq_pending[irq_buserror] = 1; | ||||
|         end else cpu_state <= cpu_state_trap; | ||||
|         cpu_state <= cpu_state_trap; | ||||
|       end | ||||
|       if (mem_wordsize == 1 && reg_op1[0] != 0) begin | ||||
|         `debug($display("MISALIGNED HALFWORD: 0x%08x", reg_op1);) | ||||
|         if (!irq_mask[irq_buserror] && !irq_active) begin | ||||
|           next_irq_pending[irq_buserror] = 1; | ||||
|         end else cpu_state <= cpu_state_trap; | ||||
|         cpu_state <= cpu_state_trap; | ||||
|       end | ||||
|     end | ||||
|     if (resetn && mem_do_rinst && (|reg_pc[1:0])) begin | ||||
|       `debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);) | ||||
|       if (!irq_mask[irq_buserror] && !irq_active) begin | ||||
|         next_irq_pending[irq_buserror] = 1; | ||||
|       end else cpu_state <= cpu_state_trap; | ||||
|       cpu_state <= cpu_state_trap; | ||||
|     end | ||||
| 
 | ||||
|     if (!resetn || mem_done) begin | ||||
|  | @ -1326,7 +1180,6 @@ module picorv32 #( | |||
|     if (set_mem_do_rdata) mem_do_rdata <= 1; | ||||
|     if (set_mem_do_wdata) mem_do_wdata <= 1; | ||||
| 
 | ||||
|     irq_pending <= next_irq_pending & ~MASKED_IRQ; | ||||
|     current_pc = 'bx; | ||||
|   end | ||||
| endmodule | ||||
|  | @ -1334,15 +1187,15 @@ endmodule | |||
| module picorv32_regs ( | ||||
|     input clk, | ||||
|     wen, | ||||
|     input [5:0] waddr, | ||||
|     input [5:0] raddr1, | ||||
|     input [5:0] raddr2, | ||||
|     input [4:0] waddr, | ||||
|     input [4:0] raddr1, | ||||
|     input [4:0] raddr2, | ||||
|     input [31:0] wdata, | ||||
|     output [31:0] rdata1, | ||||
|     output [31:0] rdata2 | ||||
| ); | ||||
|   reg [31:0] regs[0:35]; | ||||
|   always @(posedge clk) if (wen) regs[waddr[5:0]] <= wdata; | ||||
|   reg [31:0] regs[0:31]; | ||||
|   always @(posedge clk) if (wen) regs[waddr[4:0]] <= wdata; | ||||
|   assign rdata1 = regs[raddr1]; | ||||
|   assign rdata2 = regs[raddr2]; | ||||
| endmodule | ||||
|  |  | |||
|  | @ -113,10 +113,7 @@ module picorv32_wb #( | |||
| 
 | ||||
|   picorv32 #( | ||||
|       .ENABLE_TRACE(1), | ||||
|       .MASKED_IRQ(32'h0000_0000), | ||||
|       .LATCHED_IRQ(32'hffff_ffff), | ||||
|       .PROGADDR_RESET(32'h0001_0000), | ||||
|       .PROGADDR_IRQ(32'h0001_0010), | ||||
|       .STACKADDR(32'h0001_0000) | ||||
|   ) picorv32_core ( | ||||
|       .clk   (clk), | ||||
|  | @ -135,8 +132,6 @@ module picorv32_wb #( | |||
|       .mem_la_addr (mem_la_addr), | ||||
|       .mem_la_wdata(mem_la_wdata), | ||||
|       .mem_la_wstrb(mem_la_wstrb), | ||||
|       .irq         (irq), | ||||
|       .eoi         (eoi), | ||||
| 
 | ||||
|       .trace_valid(trace_valid), | ||||
|       .trace_data (trace_data), | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue