├── src ├── force_rebuild.v ├── sys_parameters.v ├── picorv32.sdc ├── reset.v ├── ws2812b_tgt.v ├── tang_nano_9k_leds.v ├── picorv32_9k.cst ├── uart_wrap.v ├── sram8bit.v ├── picorv32.cst ├── sram.v ├── countdown_timer.v ├── simpleuart.v ├── ws2812b.v ├── top.v ├── mem_init0.ini ├── mem_init1.ini ├── mem_init2.ini ├── mem_init3.ini └── picorv32.v ├── LICENSE ├── tang_20k_pinout.jpg ├── c_code ├── ws2812b.h ├── leds.h ├── ws2812b.c ├── startup.s ├── leds.c ├── uart.h ├── link_cmd.ld ├── countdown_timer.h ├── README ├── countdown_timer.c ├── uart.c ├── Makefile ├── conv_to_init.c └── main.c ├── picorv32.gprj ├── README └── impl └── project_process_config.json /src/force_rebuild.v: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | See files... 2 | -------------------------------------------------------------------------------- /src/sys_parameters.v: -------------------------------------------------------------------------------- 1 | localparam SRAM_ADDR_WIDTH = 12; 2 | localparam CLK_FREQ = 20000000; 3 | -------------------------------------------------------------------------------- /tang_20k_pinout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grughuhler/picorv32_tang_nano_20k/HEAD/tang_20k_pinout.jpg -------------------------------------------------------------------------------- /c_code/ws2812b.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2024 Grug Huhler. License SPDX BSD-2-Clause. 2 | */ 3 | 4 | #ifndef WS2812B_H 5 | #define WS2812B_H 6 | 7 | extern void set_ws2812b(unsigned int val); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /c_code/leds.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2024 Grug Huhler. License SPDX BSD-2-Clause. 2 | */ 3 | 4 | #ifndef LEDS_H 5 | #define LEDS_H 6 | 7 | extern void set_leds(unsigned char val); 8 | extern unsigned char get_leds(void); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /c_code/ws2812b.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2024 Grug Huhler. License SPDX BSD-2-Clause. 2 | */ 3 | 4 | #include "ws2812b.h" 5 | 6 | #define RGB_LED ((volatile unsigned int *) 0x80000020) 7 | 8 | void set_ws2812b(unsigned int val) 9 | { 10 | *RGB_LED = val; 11 | } 12 | -------------------------------------------------------------------------------- /src/picorv32.sdc: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2024 GOWIN Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: Timing Constraints file 4 | //GOWIN Version: 1.9.9 Beta-4 Education 5 | //Created Time: 2024-06-01 16:16:50 6 | create_clock -name clk -period 50 -waveform {0 25} [get_ports {clk}] 7 | -------------------------------------------------------------------------------- /c_code/startup.s: -------------------------------------------------------------------------------- 1 | /* Copyright 2024 Grug Huhler. License SPDX BSD-2-Clause. 2 | 3 | This is a VERY incomplete startup sequence for C. It fails to 4 | do many things such as clear bss. 5 | */ 6 | 7 | .text 8 | .global _start 9 | _start: 10 | li x2, 4*(1<> 28; 26 | *UART_DATA = "0123456789abcdef"[ch]; 27 | val = val << 4; 28 | } 29 | } 30 | 31 | char uart_getchar(void) 32 | { 33 | unsigned char ch; 34 | 35 | /* UART gives 0xff when empty */ 36 | while ((ch = *UART_DATA) == 0xff) {} 37 | 38 | return(ch); 39 | } 40 | 41 | void uart_putchar(char ch) 42 | { 43 | *UART_DATA = ch; 44 | } 45 | 46 | void uart_puts(char *s) 47 | { 48 | while (*s != 0) *UART_DATA = *s++; 49 | } 50 | 51 | unsigned int uart_get_hex(void) 52 | { 53 | unsigned int v; 54 | int keep_going; 55 | char ch; 56 | 57 | keep_going = 1; 58 | 59 | v = 0; 60 | while (keep_going) { 61 | 62 | ch = uart_getchar(); 63 | 64 | if ((ch >= '0') && (ch <= '9')) { 65 | v = 16*v + (ch - '0'); 66 | uart_putchar(ch); 67 | } else if ((ch >= 'a') && (ch <= 'f')) { 68 | v = 16*v + (ch - 'a' + 10); 69 | uart_putchar(ch); 70 | } else if ((ch >= 'A') && (ch <= 'F')) { 71 | v = 16*v + (ch - 'A' + 10); 72 | uart_putchar(ch); 73 | } else if (ch == '\r') { 74 | uart_putchar('\n'); 75 | keep_going = 0; 76 | } 77 | } 78 | 79 | return v; 80 | } 81 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This directory contains a simple SoC that uses the risc-v (32-bit) 2 | core from https://github.com/YosysHQ/picorv32. File picorv32.v is 3 | from there. It is the core. 4 | 5 | It is for the Tang Nano 20K FPGA development board. There is a 6 | similar project for the Tang Nano 9K: 7 | 8 | https://github.com/grughuhler/picorv32.git 9 | 10 | This repository is based on the infer_sram branch of that one. 11 | 12 | The Tang Nano 20K has a clock generation chip that feeds a clock to 13 | pin 10. This project assumes this as the clock source. To configure 14 | this clock to 20 MHz (the default set in Makefile): 15 | 16 | 1. Connect Tang Nano 20K USB to a computer. 17 | 2. Open a terminal emulator (115200). I like picocom on Linux. 18 | 3. Enter control-x followed by control-c and enter. You should 19 | get prompt "TangNano20K". 20 | 4. Enter command "pll_clk O0=20M -s". Note that's leter "O" and zero. 21 | 5. Enter command "choose uart" to return to connection to a UART 22 | implemented on the FPGA. 23 | 24 | File top.v is the top level module and integrates the SoC's 25 | components which are: 26 | 27 | * The risc-v core. 28 | * SRAM memory (see Makefile to set size) 29 | * A small reset controller. 30 | * A UART (wrapper around the simpleuart from 31 | https://github.com/YosysHQ/picorv32). 32 | * An LED driver that supports read and write. 33 | * A 32-bit count-down timer that can be read and written. 34 | It counts down to zero and stops. 35 | * A controller for the WS2812B RGB LED on the Tang Nano 20K. 36 | 37 | The project is intended to be very simple and direct. There are no 38 | integration abstractions. 39 | 40 | It was built using the educational version of the Gowin IDE and 41 | tool chain, 1.9.9 Beta-4 Education Build(68283). 42 | 43 | The Gowin IDE should build it. See the README in directory c_code for 44 | information on how to build the software. The program already in the 45 | memory initialization files accepts one-letter commands. S1 is the 46 | reset button. Serial port: 115200, no parity, no flow control. 47 | 48 | The SRAM is initialized by the C code and then the Verilog build 49 | process. This is how the software is "loaded". See README in 50 | the c_code directory. 51 | 52 | See https://www.youtube.com/@electronics.tinker/videos about Tang Nano 53 | FPGAs. 54 | -------------------------------------------------------------------------------- /src/sram.v: -------------------------------------------------------------------------------- 1 | /* Copyright 2024 Grug Huhler. License SPDX BSD-2-Clause. */ 2 | 3 | // Create sram using Verilog inference with each 8-bit RAM initialized 4 | // with its own init file. 5 | 6 | module sram 7 | #(parameter SRAM_ADDR_WIDTH=11) 8 | ( 9 | input wire clk, 10 | input wire reset_n, 11 | input wire sram_sel, 12 | input wire [3:0] wstrb, 13 | input wire [SRAM_ADDR_WIDTH + 1:0] addr, 14 | input wire [31:0] sram_data_i, 15 | output wire sram_ready, 16 | output wire [31:0] sram_data_o 17 | ); 18 | 19 | reg ready = 1'b0; 20 | 21 | assign sram_ready = ready; 22 | 23 | sram8 24 | #( 25 | .SRAM_ADDR_WIDTH(SRAM_ADDR_WIDTH), 26 | .MEM_INIT_FILE("mem_init3.ini") 27 | ) gmem3 28 | ( 29 | .clk(clk), 30 | .reset_n(reset_n), 31 | .ce(sram_sel), 32 | .wre(wstrb[3]), 33 | .addr(addr[SRAM_ADDR_WIDTH + 1:2]), 34 | .data_in(sram_data_i[31:24]), 35 | .data_out(sram_data_o[31:24]) 36 | ); 37 | 38 | sram8 39 | #( 40 | .SRAM_ADDR_WIDTH(SRAM_ADDR_WIDTH), 41 | .MEM_INIT_FILE("mem_init2.ini") 42 | ) gmem2 43 | ( 44 | .clk(clk), 45 | .reset_n(reset_n), 46 | .ce(sram_sel), 47 | .wre(wstrb[2]), 48 | .addr(addr[SRAM_ADDR_WIDTH + 1:2]), 49 | .data_in(sram_data_i[23:16]), 50 | .data_out(sram_data_o[23:16]) 51 | ); 52 | 53 | sram8 54 | #( 55 | .SRAM_ADDR_WIDTH(SRAM_ADDR_WIDTH), 56 | .MEM_INIT_FILE("mem_init1.ini") 57 | ) gmem1 58 | ( 59 | .clk(clk), 60 | .reset_n(reset_n), 61 | .ce(sram_sel), 62 | .wre(wstrb[1]), 63 | .addr(addr[SRAM_ADDR_WIDTH + 1:2]), 64 | .data_in(sram_data_i[15:8]), 65 | .data_out(sram_data_o[15:8]) 66 | ); 67 | 68 | sram8 69 | #( 70 | .SRAM_ADDR_WIDTH(SRAM_ADDR_WIDTH), 71 | .MEM_INIT_FILE("mem_init0.ini") 72 | ) gmem0 73 | ( 74 | .clk(clk), 75 | .reset_n(reset_n), 76 | .ce(sram_sel), 77 | .wre(wstrb[0]), 78 | .addr(addr[SRAM_ADDR_WIDTH + 1:2]), 79 | .data_in(sram_data_i[7:0]), 80 | .data_out(sram_data_o[7:0]) 81 | ); 82 | 83 | always @(posedge clk) 84 | if (sram_sel) 85 | ready <= 1'b1; 86 | else 87 | ready <= 1'b0; 88 | 89 | endmodule // sram 90 | -------------------------------------------------------------------------------- /src/countdown_timer.v: -------------------------------------------------------------------------------- 1 | /* Copyright 2024 Grug Huhler. License SPDX BSD-2-Clause. 2 | 3 | Timer that can be written and read and always counts 4 | down, stopping at zero. The implementation is intentionally 5 | overcomplicated. It meets unnecessary goals: 6 | 7 | * Operate as a litte-endian register accessable with any 8 | aligned access as a byte, half-word, or 32-bit word. 9 | * Let individual bytes of half-words be written without 10 | changing other bits in the register. 11 | * Use a state machine for cdt_ready that adds more delay 12 | than is needed. It should work just to assert READY 13 | as soon as SEL is seen. 14 | */ 15 | 16 | module countdown_timer 17 | ( 18 | input wire clk, 19 | input wire reset_n, 20 | input wire cdt_sel, 21 | input wire [31:0] cdt_data_i, 22 | input wire [3:0] we, 23 | output wire cdt_ready, 24 | output wire [31:0] cdt_data_o 25 | ); 26 | 27 | reg [1:0] delay_state = 'b0; 28 | reg [31:0] counter = 'b0; 29 | 30 | assign cdt_data_o = counter; 31 | assign cdt_ready = (delay_state == 2'b10); 32 | 33 | always @(posedge clk or negedge reset_n) 34 | if (!reset_n) 35 | delay_state <= 'b0; 36 | else 37 | case (delay_state) 38 | 2'b00: begin // Await SEL 39 | if (cdt_sel) 40 | delay_state <= 2'b01; 41 | else 42 | delay_state <= 2'b00; 43 | end 44 | 2'b01: begin // Working (for one cycle) 45 | if (cdt_sel) 46 | delay_state <= 2'b10; 47 | else 48 | delay_state <= 2'b00; 49 | end 50 | 2'b10: begin // Finished 51 | if (cdt_sel) 52 | delay_state <= 2'b11; 53 | else 54 | delay_state <= 2'b00; 55 | end 56 | 2'b11: begin // Await !cdt_sel 57 | if (cdt_sel) 58 | delay_state <= 2'b11; 59 | else 60 | delay_state <= 2'b00; 61 | end 62 | endcase 63 | 64 | always @(posedge clk or negedge reset_n) 65 | if (!reset_n) begin 66 | counter <= 'b0; 67 | end 68 | else if (cdt_sel) begin 69 | if (we) begin 70 | if (we[3]) counter[31:24] <= cdt_data_i[31:24]; 71 | if (we[2]) counter[23:16] <= cdt_data_i[23:16]; 72 | if (we[1]) counter[15:8] <= cdt_data_i[15:8]; 73 | if (we[0]) counter[7:0] <= cdt_data_i[7:0]; 74 | end 75 | else 76 | if (counter != 'b0) counter <= counter - 1; 77 | end 78 | else begin 79 | if (counter != 'b0) counter <= counter - 1; 80 | end 81 | 82 | endmodule // countdown_timer 83 | -------------------------------------------------------------------------------- /c_code/Makefile: -------------------------------------------------------------------------------- 1 | # Just run "make" to create ../src/mem_init.v 2 | 3 | 4 | # SRAM_ADDR_WIDTH sets the width of the SRAM's address in the Verilog. 5 | # This implicitly sets the total bytes of SRAM to 4*(1 << SRAM_ADDR_WIDTH) 6 | # which, in turn, sets the starting address of the stack pointer in 7 | # startup.s 8 | # 9 | # The practical values are 10 | # 11 - giving 8192 bytes of SRAM (using 4 block SRAMS). 11 | # 12 - giving 16384 bytes of SRAM (using 8 block SRAMS). 12 | # 13 - giving 32768 bytes of SRAM (using 16 block SRAMS). 13 | # 14 - giving 65536 bytes of SRAM (using 32 block SRAMS, Nano 20K only). 14 | # 15 | # The Gowin GW1NR-LV9 has only 26 block SRAMS so value 14 will fail. 16 | # The GW2AR-LV18 has 46 blocks so 14 is OK for it. 17 | # Values less than 11 will work but are pointless on this FPGA since 18 | # 4 block SRAMs will still be used. 19 | # 20 | # Note that file force_rebuild.v is empty and exists only to cause 21 | # the Gowan IDE to rebuild when this makefile has executed. 22 | 23 | SRAM_ADDR_WIDTH = 12 24 | 25 | # This tells both software and Verilog the clock speed. Change it 26 | # here only. 27 | CLK_FREQ = 20000000 28 | 29 | COMMONFLAGS = -march=rv32i2p0 -mabi=ilp32 30 | CFLAGS = -mno-save-restore $(COMMONFLAGS) -nostartfiles -nostdlib -static -O1 31 | ASFLAGS = --defsym SRAM_ADDR_WIDTH=$(SRAM_ADDR_WIDTH) $(COMMONFLAGS) 32 | LIBS = /usr/lib/gcc/riscv64-unknown-elf/10.2.0/rv32i/ilp32/libgcc.a 33 | 34 | CC = riscv64-unknown-elf-gcc 35 | OBJCOPY = riscv64-unknown-elf-objcopy 36 | OBJDUMP = riscv64-unknown-elf-objdump 37 | AS = riscv64-unknown-elf-as 38 | 39 | all: prog.hex conv_to_init 40 | 41 | conv_to_init: conv_to_init.c 42 | gcc -o conv_to_init conv_to_init.c 43 | 44 | main.o: main.c 45 | $(CC) $(CFLAGS) -DCLK_FREQ=$(CLK_FREQ) -c main.c 46 | 47 | countdown_timer.o: countdown_timer.c 48 | $(CC) $(CFLAGS) -c countdown_timer.c 49 | 50 | uart.o: uart.c 51 | $(CC) $(CFLAGS) -c uart.c 52 | 53 | leds.o: leds.c 54 | $(CC) $(CFLAGS) -c leds.c 55 | 56 | ws2812b.o: ws2812b.c 57 | $(CC) $(CFLAGS) -c ws2812b.c 58 | 59 | startup.o: startup.s Makefile 60 | $(AS) $(ASFLAGS) -o startup.o startup.s 61 | 62 | prog.elf: startup.o main.o countdown_timer.o uart.o leds.o ws2812b.o 63 | $(CC) $(CFLAGS) -Tlink_cmd.ld -o prog.elf startup.o main.o countdown_timer.o \ 64 | uart.o leds.o ws2812b.o $(LIBS) 65 | 66 | prog.bin: prog.elf conv_to_init Makefile 67 | $(OBJCOPY) prog.elf -O binary prog.bin 68 | rm -f ../src/mem_init[0-3].ini ../src/sys_parameters.v 69 | ./conv_to_init $(CLK_FREQ) $(SRAM_ADDR_WIDTH) prog.bin 70 | touch ../src/force_rebuild.v 71 | 72 | prog.hex: prog.bin 73 | od -v -Ax -t x4 prog.bin > prog.hex 74 | 75 | clean: 76 | rm -f prog.elf prog.hex prog.bin main.o conv_to_init countdown_timer.o uart.o \ 77 | startup.o leds.o ws2812b.o 78 | 79 | -------------------------------------------------------------------------------- /c_code/conv_to_init.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2024 Grug Huhler. License SPDX BSD-2-Clause. 2 | 3 | This program converts a binary file into four text files 4 | that are used to initialize four inferred 8-bit wide 5 | SRAMs used in the picorv32 project. 6 | 7 | Usage: conv_to_init sram_addr_width input_file_name 8 | 9 | The memory is then assumed to be 4*2**addr_with bytes 10 | The output file names are fixed: 11 | 12 | 1. ../src/sys_parameters.v 13 | 14 | This file contains the lines 15 | 16 | localparam SRAM_ADDR_WIDTH = sram_addr_width; 17 | localparam CLK_FREQ = clk_freq; 18 | 19 | and is used to set this Verilog parameter. 20 | 21 | 2. ../src/mem_initX.ini, where X = 0, 1, 2, 3. 22 | File mem_init0.ini contains the least significant byte. 23 | 24 | See the Makefile. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | int main(int argc, char **argv) 32 | { 33 | char fname[80]; 34 | FILE *fp_in, *fp_param, *fp_out[4]; 35 | int v, i, byte_count = 0; 36 | int sram_addr_width, mem_bytes, clk_freq; 37 | 38 | if (argc != 4) { 39 | fprintf(stderr, "Usage: conv_to_init clk_freq sram_addr_width filename\n"); 40 | exit(EXIT_FAILURE); 41 | } 42 | 43 | clk_freq = atoi(argv[1]); 44 | if (clk_freq <= 0) { 45 | fprintf(stderr, "clk_freq must be posiive\n"); 46 | exit(EXIT_FAILURE); 47 | } 48 | 49 | sram_addr_width = atoi(argv[2]); 50 | if (sram_addr_width <= 0) { 51 | fprintf(stderr, "sram_addr_width must be posiive\n"); 52 | exit(EXIT_FAILURE); 53 | } 54 | 55 | mem_bytes = 4*(1 << sram_addr_width); 56 | 57 | fp_in = fopen(argv[3], "rb"); 58 | if (fp_in == NULL) { 59 | fprintf(stderr, "Could not open %s\n", argv[3]); 60 | exit(EXIT_FAILURE); 61 | } 62 | 63 | for (i = 0; i < 4; i++) { 64 | 65 | sprintf(fname, "../src/mem_init%d.ini", i); 66 | 67 | fp_out[i] = fopen(fname, "wb"); 68 | if (fp_out[i] == NULL) { 69 | fprintf(stderr, "could not open file %s\n", fname); 70 | exit(EXIT_FAILURE); 71 | } 72 | } 73 | 74 | fp_param = fopen("../src/sys_parameters.v", "w"); 75 | if (fp_param == NULL) { 76 | fprintf(stderr, "could not open file %s\n", "../src/sys_parameters.v"); 77 | exit(EXIT_FAILURE); 78 | } 79 | fprintf(fp_param, "localparam SRAM_ADDR_WIDTH = %d;\n", sram_addr_width); 80 | fprintf(fp_param, "localparam CLK_FREQ = %d;\n", clk_freq); 81 | fclose(fp_param); 82 | 83 | while ((v = fgetc(fp_in)) != EOF) { 84 | fprintf(fp_out[byte_count % 4], "%02X\n", v); 85 | byte_count += 1; 86 | } 87 | 88 | /* Initialize to 16 byte boundary just in case */ 89 | while ((byte_count % 16) != 0) { 90 | fprintf(fp_out[byte_count % 4], "%02X\n", 0); 91 | byte_count += 1; 92 | } 93 | 94 | fclose(fp_in); 95 | for (i = 0; i < 4; i++) fclose(fp_out[i]); 96 | 97 | if (byte_count > mem_bytes) { 98 | fprintf(stderr, "ERROR: PROGRAM IS TOO LARGE: %d bytes is\n", byte_count); 99 | fprintf(stderr, " greater than %d bytes\n", mem_bytes); 100 | fprintf(stderr, "And don't forget to leave room for the stack\n"); 101 | return(EXIT_FAILURE); 102 | } 103 | 104 | printf("NOTE: program occupies %d bytes\n", byte_count); 105 | 106 | return EXIT_SUCCESS; 107 | } 108 | -------------------------------------------------------------------------------- /impl/project_process_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "Allow_Duplicate_Modules" : false, 3 | "Annotated_Properties_for_Analyst" : true, 4 | "BACKGROUND_PROGRAMMING" : "off", 5 | "CMSER" : false, 6 | "CMSER_CHECKSUM" : false, 7 | "CMSER_MODE" : "auto", 8 | "COMPRESS" : false, 9 | "CPU" : false, 10 | "CRC_CHECK" : true, 11 | "Clock_Conversion" : true, 12 | "Clock_Route_Order" : 0, 13 | "Correct_Hold_Violation" : true, 14 | "DONE" : false, 15 | "DOWNLOAD_SPEED" : "default", 16 | "Default_Enum_Encoding" : "default", 17 | "Disable_Insert_Pad" : false, 18 | "ENABLE_MERGE_MODE" : false, 19 | "ENCRYPTION_KEY" : false, 20 | "ENCRYPTION_KEY_TEXT" : "00000000000000000000000000000000", 21 | "ERROR_DECTION_AND_CORRECTION" : false, 22 | "ERROR_DECTION_ONLY" : false, 23 | "ERROR_INJECTION" : false, 24 | "EXTERNAL_MASTER_CONFIG_CLOCK" : false, 25 | "FORMAT" : "binary", 26 | "FREQUENCY_DIVIDER" : "", 27 | "FSM Compiler" : true, 28 | "Fanout_Guide" : 10000, 29 | "Frequency" : "Auto", 30 | "Generate_Constraint_File_of_Ports" : false, 31 | "Generate_IBIS_File" : false, 32 | "Generate_Plain_Text_Timing_Report" : false, 33 | "Generate_Post_PNR_Simulation_Model_File" : false, 34 | "Generate_Post_Place_File" : false, 35 | "Generate_SDF_File" : false, 36 | "Generate_VHDL_Post_PNR_Simulation_Model_File" : false, 37 | "GwSyn_Loop_Limit" : 2000, 38 | "HOTBOOT" : false, 39 | "I2C" : false, 40 | "I2C_SLAVE_ADDR" : "00", 41 | "Implicit_Initial_Value_Support" : false, 42 | "IncludePath" : [ 43 | 44 | ], 45 | "Incremental_Compile" : "", 46 | "Initialize_Primitives" : false, 47 | "JTAG" : false, 48 | "MODE_IO" : false, 49 | "MSPI" : false, 50 | "MSPI_JUMP" : false, 51 | "MULTIBOOT_ADDRESS_WIDTH" : "24", 52 | "MULTIBOOT_MODE" : "Normal", 53 | "MULTIBOOT_SPI_FLASH_ADDRESS" : "00000000", 54 | "MULTIJUMP_ADDRESS_WIDTH" : "24", 55 | "MULTIJUMP_MODE" : "Normal", 56 | "MULTIJUMP_SPI_FLASH_ADDRESS" : "000000", 57 | "Multi_Boot" : true, 58 | "Multiple_File_Compilation_Unit" : true, 59 | "Number_of_Critical_Paths" : "", 60 | "Number_of_Start/End_Points" : "", 61 | "OSC_DIVIDER" : "8", 62 | "OUTPUT_BASE_NAME" : "picorv32", 63 | "POWER_ON_RESET_MONITOR" : true, 64 | "PRINT_BSRAM_VALUE" : true, 65 | "PROGRAM_DONE_BYPASS" : false, 66 | "Pipelining" : true, 67 | "PlaceInRegToIob" : true, 68 | "PlaceIoRegToIob" : true, 69 | "PlaceOutRegToIob" : true, 70 | "Place_Option" : "0", 71 | "Process_Configuration_Verion" : "1.0", 72 | "Promote_Physical_Constraint_Warning_to_Error" : true, 73 | "Push_Tristates" : true, 74 | "READY" : false, 75 | "RECONFIG_N" : false, 76 | "Ram_RW_Check" : false, 77 | "Replicate_Resources" : false, 78 | "Report_Auto-Placed_Io_Information" : false, 79 | "Resolve_Mixed_Drivers" : false, 80 | "Resource_Sharing" : true, 81 | "Retiming" : false, 82 | "Route_Maxfan" : 23, 83 | "Route_Option" : "0", 84 | "Run_Timing_Driven" : true, 85 | "SECURE_MODE" : false, 86 | "SECURITY_BIT" : true, 87 | "SSPI" : false, 88 | "STOP_CMSER" : false, 89 | "Show_All_Warnings" : false, 90 | "Synthesis On/Off Implemented as Translate On/Off" : false, 91 | "Synthesize_tool" : "GowinSyn", 92 | "TclPre" : "", 93 | "TopModule" : "top", 94 | "USERCODE" : "default", 95 | "Unused_Pin" : "As_input_tri_stated_with_pull_up", 96 | "Update_Compile_Point_Timing_Data" : false, 97 | "Use_Clock_Period_for_Unconstrainted IO" : false, 98 | "VCCAUX" : 3.3, 99 | "VCCX" : "3.3", 100 | "VHDL_Standard" : "VHDL_Std_1993", 101 | "Verilog_Standard" : "Vlg_Std_2001", 102 | "WAKE_UP" : "0", 103 | "Write_Vendor_Constraint_File" : true, 104 | "show_all_warnings" : false, 105 | "turn_off_bg" : false 106 | } -------------------------------------------------------------------------------- /src/simpleuart.v: -------------------------------------------------------------------------------- 1 | /* 2 | * PicoSoC - A simple example SoC using PicoRV32 3 | * 4 | * Copyright (C) 2017 Claire Xenia Wolf 5 | * 6 | * Permission to use, copy, modify, and/or distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | * 18 | */ 19 | 20 | module simpleuart #(parameter integer DEFAULT_DIV = 1) ( 21 | input clk, 22 | input resetn, 23 | 24 | output ser_tx, 25 | input ser_rx, 26 | 27 | input [3:0] reg_div_we, 28 | input [31:0] reg_div_di, 29 | output [31:0] reg_div_do, 30 | 31 | input reg_dat_we, 32 | input reg_dat_re, 33 | input [31:0] reg_dat_di, 34 | output [31:0] reg_dat_do, 35 | output reg_dat_wait 36 | ); 37 | reg [31:0] cfg_divider; 38 | 39 | reg [3:0] recv_state; 40 | reg [31:0] recv_divcnt; 41 | reg [7:0] recv_pattern; 42 | reg [7:0] recv_buf_data; 43 | reg recv_buf_valid; 44 | 45 | reg [9:0] send_pattern; 46 | reg [3:0] send_bitcnt; 47 | reg [31:0] send_divcnt; 48 | reg send_dummy; 49 | 50 | assign reg_div_do = cfg_divider; 51 | 52 | assign reg_dat_wait = reg_dat_we && (send_bitcnt || send_dummy); 53 | assign reg_dat_do = recv_buf_valid ? recv_buf_data : ~0; 54 | 55 | always @(posedge clk) begin 56 | if (!resetn) begin 57 | cfg_divider <= DEFAULT_DIV; 58 | end else begin 59 | if (reg_div_we[0]) cfg_divider[ 7: 0] <= reg_div_di[ 7: 0]; 60 | if (reg_div_we[1]) cfg_divider[15: 8] <= reg_div_di[15: 8]; 61 | if (reg_div_we[2]) cfg_divider[23:16] <= reg_div_di[23:16]; 62 | if (reg_div_we[3]) cfg_divider[31:24] <= reg_div_di[31:24]; 63 | end 64 | end 65 | 66 | always @(posedge clk) begin 67 | if (!resetn) begin 68 | recv_state <= 0; 69 | recv_divcnt <= 0; 70 | recv_pattern <= 0; 71 | recv_buf_data <= 0; 72 | recv_buf_valid <= 0; 73 | end else begin 74 | recv_divcnt <= recv_divcnt + 1; 75 | if (reg_dat_re) 76 | recv_buf_valid <= 0; 77 | case (recv_state) 78 | 0: begin 79 | if (!ser_rx) 80 | recv_state <= 1; 81 | recv_divcnt <= 0; 82 | end 83 | 1: begin 84 | if (2*recv_divcnt > cfg_divider) begin 85 | recv_state <= 2; 86 | recv_divcnt <= 0; 87 | end 88 | end 89 | 10: begin 90 | if (recv_divcnt > cfg_divider) begin 91 | recv_buf_data <= recv_pattern; 92 | recv_buf_valid <= 1; 93 | recv_state <= 0; 94 | end 95 | end 96 | default: begin 97 | if (recv_divcnt > cfg_divider) begin 98 | recv_pattern <= {ser_rx, recv_pattern[7:1]}; 99 | recv_state <= recv_state + 1; 100 | recv_divcnt <= 0; 101 | end 102 | end 103 | endcase 104 | end 105 | end 106 | 107 | assign ser_tx = send_pattern[0]; 108 | 109 | always @(posedge clk) begin 110 | if (reg_div_we) 111 | send_dummy <= 1; 112 | send_divcnt <= send_divcnt + 1; 113 | if (!resetn) begin 114 | send_pattern <= ~0; 115 | send_bitcnt <= 0; 116 | send_divcnt <= 0; 117 | send_dummy <= 1; 118 | end else begin 119 | if (send_dummy && !send_bitcnt) begin 120 | send_pattern <= ~0; 121 | send_bitcnt <= 15; 122 | send_divcnt <= 0; 123 | send_dummy <= 0; 124 | end else 125 | if (reg_dat_we && !send_bitcnt) begin 126 | send_pattern <= {1'b1, reg_dat_di[7:0], 1'b0}; 127 | send_bitcnt <= 10; 128 | send_divcnt <= 0; 129 | end else 130 | if (send_divcnt > cfg_divider && send_bitcnt) begin 131 | send_pattern <= {1'b1, send_pattern[9:1]}; 132 | send_bitcnt <= send_bitcnt - 1; 133 | send_divcnt <= 0; 134 | end 135 | end 136 | end 137 | endmodule 138 | -------------------------------------------------------------------------------- /src/ws2812b.v: -------------------------------------------------------------------------------- 1 | /* Copyright 2024 Grug Huhler. License SPDX BSD-2-Clause. 2 | * 3 | * This module controls a single ws2812b RBG addressable LED. 4 | * 5 | * When the module asserts can_accept, it will accept data to display 6 | * on the next rising clock edge when ena is also asserted. 7 | * 8 | * Data are three bytes: {G[7:0],R[7:0],B[7:0]} where the G, 9 | * R, and B values control the bightness of those colors. 10 | */ 11 | 12 | module ws2812b #(parameter CLK_FREQ = 20e6) 13 | ( 14 | input wire clk, 15 | input wire reset_n, 16 | input wire [23:0] data_in, 17 | input wire ena, 18 | output wire can_accept, 19 | output reg to_din 20 | ); 21 | 22 | /* states */ 23 | localparam IDLE = 3'b000; 24 | localparam CHK_COUNT = 3'b001; 25 | localparam SEND_HI = 3'b010; 26 | localparam SEND_LO = 3'b011; 27 | localparam SEND_RES = 3'b100; 28 | 29 | /* WS2812B timing. Each bit is encoded by holding din high for a time 30 | * followed by holding it low for a time: 31 | * 0: time high: 0.4us, low: 0.85us (all times have 32 | * 1: time high: 0.8us, low: 0.45us margin +/- 150ns) 33 | * After all LEDs in a string are set, hold din low for "reset" time 34 | * of at least 300us. Reg cycle_counter must be wide enough for this. 35 | * You will also have problems if clock is too slow. 5 MHz is near the 36 | * lower limit for accurate timing. 37 | */ 38 | 39 | localparam CLKS_PER_BIT = $rtoi(CLK_FREQ*1.25e-6 + 0.5); 40 | localparam T0H_CLKS = $rtoi(CLK_FREQ*0.4e-6 + 0.5); 41 | localparam T0L_CLKS = CLKS_PER_BIT - T0H_CLKS; 42 | localparam T1H_CLKS = $rtoi(CLK_FREQ*0.8e-6 + 0.5); 43 | localparam T1L_CLKS = CLKS_PER_BIT - T1H_CLKS; 44 | localparam RES_CLKS = $rtoi(CLK_FREQ*302e-6 + 0.5); 45 | 46 | reg [4:0] bit_counter; 47 | reg [14:0] cycle_counter; 48 | reg [2:0] state = IDLE; 49 | reg [23:0] grb_val; 50 | 51 | assign can_accept = (state == IDLE); 52 | 53 | always @(posedge clk or negedge reset_n) 54 | if (~reset_n) begin 55 | state <= IDLE; 56 | grb_val <= 1'b0; 57 | bit_counter <= 'b0; 58 | cycle_counter <= 'b0; 59 | to_din <= 1'b0; 60 | end 61 | else 62 | case (state) 63 | IDLE: 64 | begin 65 | to_din <= 1'b0; 66 | bit_counter <= 24; 67 | grb_val <= data_in; 68 | if (ena) 69 | state <= CHK_COUNT; 70 | else 71 | state <= IDLE; 72 | end 73 | CHK_COUNT: 74 | begin 75 | if (bit_counter > 'b0) begin 76 | cycle_counter <= grb_val[23] ? T1H_CLKS - 1 : T0H_CLKS - 1; 77 | state <= SEND_HI; 78 | end 79 | else begin 80 | cycle_counter <= RES_CLKS; 81 | state <= SEND_RES; 82 | end 83 | end 84 | SEND_HI: 85 | begin 86 | to_din <= 1'b1; 87 | if (cycle_counter > 'b0) begin 88 | cycle_counter <= cycle_counter - 1; 89 | state <= SEND_HI; 90 | end 91 | else begin 92 | cycle_counter <= grb_val[23] ? T1L_CLKS - 2 : T0L_CLKS - 2; 93 | state <= SEND_LO; 94 | end 95 | end 96 | SEND_LO: 97 | begin 98 | to_din <= 1'b0; 99 | if (cycle_counter > 'b0) begin 100 | cycle_counter <= cycle_counter - 1; 101 | state <= SEND_LO; 102 | end 103 | else begin 104 | bit_counter <= bit_counter - 1; 105 | grb_val <= {grb_val[22:0], 1'b0}; 106 | state <= CHK_COUNT; 107 | end 108 | end 109 | SEND_RES: 110 | begin 111 | to_din <= 1'b0; 112 | if (cycle_counter > 'b0) begin 113 | cycle_counter <= cycle_counter - 1; 114 | state <= SEND_RES; 115 | end 116 | else begin 117 | state <= IDLE; 118 | end 119 | end 120 | endcase 121 | 122 | endmodule 123 | -------------------------------------------------------------------------------- /c_code/main.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2024 Grug Huhler. License SPDX BSD-2-Clause. 2 | 3 | This program shows counting on the LEDs of the Tang Nano 4 | 9K FPGA development board. 5 | 6 | Function foo lets one see stores of different size and alignment by 7 | looking at the wstrb signals from the pico32rv. 8 | */ 9 | 10 | #include "leds.h" 11 | #include "ws2812b.h" 12 | #include "uart.h" 13 | #include "countdown_timer.h" 14 | 15 | #define MEMSIZE 512 16 | unsigned int mem[MEMSIZE]; 17 | unsigned int test_vals[] = {0, 0xffffffff, 0xaaaaaaaa, 0x55555555, 0xdeadbeef}; 18 | 19 | /* A simple memory test. Delete this and also array mem 20 | above to free much of the SRAM for other things 21 | */ 22 | 23 | int mem_test (void) 24 | { 25 | int i, test, errors; 26 | unsigned int val, val_read; 27 | 28 | errors = 0; 29 | for (test = 0; test < sizeof(test_vals)/sizeof(test_vals[0]); test++) { 30 | 31 | for (i = 0; i < MEMSIZE; i++) mem[i] = test_vals[test]; 32 | 33 | for (i = 0; i < MEMSIZE; i++) { 34 | val_read = mem[i]; 35 | if (val_read != test_vals[test]) errors += 1; 36 | } 37 | } 38 | 39 | for (i = 0; i < MEMSIZE; i++) mem[i] = i + (i << 17); 40 | 41 | for (i = 0; i < MEMSIZE; i++) { 42 | val_read = mem[i]; 43 | if (val_read != i + (i << 17)) errors += 1; 44 | } 45 | 46 | return(errors); 47 | } 48 | 49 | /* The picorv32 core implements several counters and 50 | instructions to access them. These are part of the 51 | risc-v specification. Function readtime uses one 52 | of them. 53 | */ 54 | 55 | static inline unsigned int readtime(void) 56 | { 57 | unsigned int val; 58 | unsigned long long jj; 59 | asm volatile("rdtime %0" : "=r" (val)); 60 | return val; 61 | 62 | } 63 | 64 | void endian_test(void) 65 | { 66 | volatile unsigned int test_loc = 0; 67 | volatile unsigned int *addr = &test_loc; 68 | volatile unsigned char *cp0, *cp3; 69 | char byte0, byte3; 70 | unsigned int i, ok; 71 | 72 | cp0 = (volatile unsigned char *) addr; 73 | cp3 = cp0 + 3; 74 | *addr = 0x44332211; 75 | byte0 = *cp0; 76 | byte3 = *cp3; 77 | *cp3 = 0xab; 78 | i = *addr; 79 | 80 | ok = (byte0 == 0x11) && (byte3 == 0x44) && (i == 0xab332211); 81 | uart_puts("\r\nEndian test: at "); 82 | uart_print_hex((unsigned int) addr); 83 | uart_puts(", byte0: "); 84 | uart_print_hex((unsigned int) byte0); 85 | uart_puts(", byte3: "); 86 | uart_print_hex((unsigned int) byte3); 87 | uart_puts(",\r\n word: "); 88 | uart_print_hex(i); 89 | if (ok) 90 | uart_puts(" [PASSED]\r\n"); 91 | else 92 | uart_puts(" [FAILED]\r\n"); 93 | } 94 | 95 | void uart_rx_test(void) 96 | { 97 | char buf[5]; 98 | int i; 99 | 100 | uart_puts("Type 4 characters (they will echo): "); 101 | for (i = 0; i < 4; i++) { 102 | buf[i] = uart_getchar(); 103 | uart_putchar(buf[i]); 104 | } 105 | buf[4] = 0; 106 | uart_puts("\r\nUART read: "); 107 | uart_puts(buf); 108 | uart_puts("\r\n"); 109 | } 110 | 111 | /* la_functions are useful for looking at the bus using a logic 112 | analyzer. 113 | */ 114 | 115 | void la_wtest(void) 116 | { 117 | unsigned int v; 118 | volatile unsigned int *ip = (volatile unsigned int *) &v; 119 | volatile unsigned short *sp = (volatile unsigned short *) &v; 120 | volatile unsigned char *cp = (volatile unsigned char *) &v; 121 | 122 | *ip = 0x03020100; // addr 0x00 123 | 124 | *sp = 0x0302; // addr 0x00 125 | *(sp+1) = 0x0100; // addr 0x02 126 | 127 | *cp = 0x03; // addr 0x00 128 | *(cp+1) = 0x02; // addr 0x01 129 | *(cp+2) = 0x01; // addr 0x02 130 | *(cp+3) = 0x00; // addr 0x03 131 | } 132 | 133 | 134 | void la_rtest(void) 135 | { 136 | unsigned int v; 137 | volatile unsigned int *ip = (volatile unsigned int *) &v; 138 | volatile unsigned short *sp = (volatile unsigned short *) &v; 139 | volatile unsigned char *cp = (volatile unsigned char *) &v; 140 | 141 | *ip = 0x03020100; // addr 0x00 142 | 143 | *ip; // addr 0x00 144 | 145 | *sp; // addr 0x00 146 | *(sp+1); // addr 0x02 147 | 148 | *cp; // addr 0x00 149 | *(cp+1); // addr 0x01 150 | *(cp+2); // addr 0x02 151 | *(cp+3); // addr 0x03 152 | } 153 | 154 | 155 | void cdt_test(void) 156 | { 157 | unsigned int val; 158 | unsigned int test_errors = 0; 159 | 160 | // If register is little-endian, write to 0x80000013 should set 161 | // the MSB, Does it? 162 | 163 | cdt_wbyte3(0xff); 164 | val = cdt_read(); 165 | if ((val == 0xff000000) || (val < 0xfe000000)) test_errors = 1; 166 | 167 | // Write zero to most significant half-word. 168 | cdt_whalf2(0); 169 | val = cdt_read(); 170 | if (val > 0xffff) test_errors |= 2; 171 | 172 | uart_puts("Countdown timer test "); 173 | if (test_errors) { 174 | uart_puts("FAILED, mask = "); 175 | uart_print_hex(test_errors); 176 | uart_puts("\r\n"); 177 | } else { 178 | uart_puts("PASSED\r\n"); 179 | } 180 | } 181 | 182 | int main() 183 | { 184 | unsigned char v, ch; 185 | 186 | set_leds(6); 187 | la_wtest(); 188 | la_rtest(); 189 | 190 | uart_set_div(CLK_FREQ/115200.0 + 0.5); 191 | 192 | uart_puts("\r\nStarting, CLK_FREQ: 0x"); 193 | uart_print_hex(CLK_FREQ); 194 | uart_puts("\r\n\r\n"); 195 | 196 | while (1) { 197 | uart_puts("Enter command:\r\n"); 198 | uart_puts(" c: countdown timer test\r\n"); 199 | uart_puts(" d: delay 3 seconds\r\n"); 200 | uart_puts(" e: endian test\r\n"); 201 | uart_puts(" g: read LED value\r\n"); 202 | uart_puts(" i: increment LED value\r\n"); 203 | uart_puts(" l: set RGB LED\r\n"); 204 | uart_puts(" m: memory test\r\n"); 205 | uart_puts(" r: read clock\r\n"); 206 | ch = uart_getchar(); 207 | switch (ch) { 208 | case 'c': 209 | cdt_test(); 210 | break; 211 | case 'e': 212 | endian_test(); 213 | break; 214 | case 'd': 215 | cdt_delay(3*CLK_FREQ); 216 | uart_puts("delay done\r\n"); 217 | break; 218 | case 'g': 219 | v = get_leds(); 220 | uart_puts("LED = "); 221 | uart_print_hex(v); 222 | uart_puts("\r\n"); 223 | break; 224 | case 'i': 225 | v = get_leds(); 226 | set_leds(v+1); 227 | break; 228 | case 'l': 229 | uart_puts(" enter 6 hex digits: "); 230 | set_ws2812b(uart_get_hex()); 231 | uart_puts("\r\n"); 232 | break; 233 | case 'm': 234 | if (mem_test()) 235 | uart_puts("memory test FAILED.\r\n"); 236 | else 237 | uart_puts("memory test PASSED.\r\n"); 238 | break; 239 | case 'r': 240 | uart_puts("time is "); 241 | uart_print_hex(readtime()); 242 | uart_puts("\r\n"); 243 | break; 244 | default: 245 | uart_puts(" Try again...\r\n"); 246 | break; 247 | } 248 | } 249 | 250 | return 0; 251 | } 252 | -------------------------------------------------------------------------------- /src/top.v: -------------------------------------------------------------------------------- 1 | /* Copyright 2024 Grug Huhler. License SPDX BSD-2-Clause. */ 2 | /* 3 | Top level module of simple SoC based on picorv32 4 | 5 | It includes: 6 | * the picorv32 core 7 | * An 8192 byte SRAM which is initialzed within the Verilog. 8 | * A module to read/write LEDs on the Gowin Tang Nano 9K 9 | * A wrapped version of the UART from picorv32's picosoc. 10 | * A 32-bit count down timer. 11 | 12 | Built and tested with the Gowin Eductional tool set on Tang Nano 9K. 13 | 14 | The picorv32 core has a very simple memory interface. 15 | See https://github.com/YosysHQ/picorv32 16 | 17 | In this SoC, slave (target) device has signals: 18 | 19 | * SLAVE_sel - this is asserted when mem_valid == 1 and mem_addr targets the slave. 20 | It "tells" the slave that it is active. It must accept a write for provide data 21 | for a read. 22 | * SLAVE_ready - this is asserted by the slave when it is done with the transaction. 23 | Core signal mem_ready is the OR of all of the SLAVE_ready signals. 24 | * Core mem_addr, mem_wdata, and mem_wstrb can be passed to all slaves directly. 25 | The latter is a byte lane enable for writes. 26 | * Each slave drives SLAVE_data_o. The core's mem_rdata is formed by selecting the 27 | correct SLAVE_data_o based on SLAVE_sel. 28 | */ 29 | 30 | // Define this for logic analyer connections and enable picorv32_la.cst. 31 | //`define USE_LA 32 | 33 | module top ( 34 | input wire clk, 35 | input wire reset_button, 36 | input wire uart_rx, 37 | output wire uart_tx, 38 | output wire ws2812b_din, 39 | `ifdef USE_LA 40 | output wire clk_out, 41 | output wire mem_instr, 42 | output wire mem_valid, 43 | output wire mem_ready, 44 | output wire b25, 45 | output wire b24, 46 | output wire b17, 47 | output wire b16, 48 | output wire b09, 49 | output wire b08, 50 | output wire b01, 51 | output wire b00, 52 | output wire [3:0] mem_wstrb, 53 | `endif 54 | output wire [5:0] leds 55 | ); 56 | 57 | // This include gets SRAM_ADDR_WIDTH and CLK_FREQ from software build process 58 | `include "sys_parameters.v" 59 | 60 | parameter BARREL_SHIFTER = 0; 61 | parameter ENABLE_MUL = 0; 62 | parameter ENABLE_DIV = 0; 63 | parameter ENABLE_FAST_MUL = 0; 64 | parameter ENABLE_COMPRESSED = 0; 65 | parameter ENABLE_IRQ_QREGS = 0; 66 | 67 | parameter MEMBYTES = 4*(1 << SRAM_ADDR_WIDTH); 68 | parameter [31:0] STACKADDR = (MEMBYTES); // Grows down. Software should set it. 69 | parameter [31:0] PROGADDR_RESET = 32'h0000_0000; 70 | parameter [31:0] PROGADDR_IRQ = 32'h0000_0000; 71 | 72 | wire reset_n; 73 | wire mem_valid; 74 | wire mem_instr; 75 | wire [31:0] mem_addr; 76 | wire [31:0] mem_wdata; 77 | wire [31:0] mem_rdata; 78 | wire [3:0] mem_wstrb; 79 | wire mem_ready; 80 | wire mem_inst; 81 | wire leds_sel; 82 | wire leds_ready; 83 | wire [31:0] leds_data_o; 84 | wire sram_sel; 85 | wire sram_ready; 86 | wire [31:0] sram_data_o; 87 | wire cdt_sel; 88 | wire cdt_ready; 89 | wire [31:0] cdt_data_o; 90 | wire uart_sel; 91 | wire [31:0] uart_data_o; 92 | wire uart_ready; 93 | wire ws2812b_sel; 94 | wire ws2812b_ready; 95 | 96 | `ifdef USE_LA 97 | // Assigns for external logic analyzer connction 98 | assign clk_out = clk; 99 | assign b25 = mem_rdata[25]; 100 | assign b24 = mem_rdata[24]; 101 | assign b17 = mem_rdata[17]; 102 | assign b16 = mem_rdata[16]; 103 | assign b09 = mem_rdata[9]; 104 | assign b08 = mem_rdata[8]; 105 | assign b01 = mem_rdata[1]; 106 | assign b00 = mem_rdata[0]; 107 | `endif 108 | 109 | // Establish memory map for all slaves: 110 | // SRAM 00000000 - 0001ffff 111 | // LED 80000000 112 | // UART 80000008 - 8000000f 113 | // CDT 80000010 - 80000014 114 | // WS2812B 80000020 - 80000024 115 | assign sram_sel = mem_valid && (mem_addr < MEMBYTES); 116 | assign leds_sel = mem_valid && (mem_addr == 32'h80000000); 117 | assign uart_sel = mem_valid && ((mem_addr & 32'hfffffff8) == 32'h80000008); 118 | assign cdt_sel = mem_valid && (mem_addr == 32'h80000010); 119 | assign ws2812b_sel = mem_valid && (mem_addr == 32'h80000020); 120 | 121 | // Core can proceed regardless of *which* slave was targetted and is now ready. 122 | assign mem_ready = mem_valid & (sram_ready | leds_ready | uart_ready | cdt_ready | ws2812b_ready); 123 | 124 | 125 | // Select which slave's output data is to be fed to core. 126 | assign mem_rdata = sram_sel ? sram_data_o : 127 | leds_sel ? leds_data_o : 128 | uart_sel ? uart_data_o : 129 | cdt_sel ? cdt_data_o : 32'h0; 130 | 131 | assign leds = ~leds_data_o[5:0]; // Connect to the LEDs off the FPGA 132 | 133 | reset_control reset_controller 134 | ( 135 | .clk(clk), 136 | .reset_button(reset_button), 137 | .reset_n(reset_n) 138 | ); 139 | 140 | uart_wrap uart 141 | ( 142 | .clk(clk), 143 | .reset_n(reset_n), 144 | .uart_tx(uart_tx), 145 | .uart_rx(uart_rx), 146 | .uart_sel(uart_sel), 147 | .addr(mem_addr[3:0]), 148 | .uart_wstrb(mem_wstrb), 149 | .uart_di(mem_wdata), 150 | .uart_do(uart_data_o), 151 | .uart_ready(uart_ready) 152 | ); 153 | 154 | countdown_timer cdt 155 | ( 156 | .clk(clk), 157 | .reset_n(reset_n), 158 | .cdt_sel(cdt_sel), 159 | .cdt_data_i(mem_wdata), 160 | .we(mem_wstrb), 161 | .cdt_ready(cdt_ready), 162 | .cdt_data_o(cdt_data_o) 163 | ); 164 | 165 | /* ws2812b_tgt is 32b write only */ 166 | ws2812b_tgt #(.CLK_FREQ(CLK_FREQ)) ws2812b_led 167 | ( 168 | .clk(clk), 169 | .reset_n(reset_n), 170 | .ws2812b_sel(ws2812b_sel), 171 | .we(&mem_wstrb), 172 | .wdata({mem_wdata[15:8], mem_wdata[23:16], mem_wdata[7:0]}), 173 | .ws2812b_ready(ws2812b_ready), 174 | .to_din(ws2812b_din) 175 | ); 176 | 177 | sram #(.SRAM_ADDR_WIDTH(SRAM_ADDR_WIDTH)) memory 178 | ( 179 | .clk(clk), 180 | .reset_n(reset_n), 181 | .sram_sel(sram_sel), 182 | .wstrb(mem_wstrb), 183 | .addr(mem_addr[SRAM_ADDR_WIDTH + 1:0]), 184 | .sram_data_i(mem_wdata), 185 | .sram_ready(sram_ready), 186 | .sram_data_o(sram_data_o) 187 | ); 188 | 189 | tang_leds soc_leds 190 | ( 191 | .clk(clk), 192 | .reset_n(reset_n), 193 | .leds_sel(leds_sel), 194 | .leds_data_i(mem_wdata[5:0]), 195 | .we(mem_wstrb[0]), 196 | .leds_ready(leds_ready), 197 | .leds_data_o(leds_data_o) 198 | ); 199 | 200 | picorv32 201 | #( 202 | .STACKADDR(STACKADDR), 203 | .PROGADDR_RESET(PROGADDR_RESET), 204 | .PROGADDR_IRQ(PROGADDR_IRQ), 205 | .BARREL_SHIFTER(BARREL_SHIFTER), 206 | .COMPRESSED_ISA(ENABLE_COMPRESSED), 207 | .ENABLE_MUL(ENABLE_MUL), 208 | .ENABLE_DIV(ENABLE_DIV), 209 | .ENABLE_FAST_MUL(ENABLE_FAST_MUL), 210 | .ENABLE_IRQ(1), 211 | .ENABLE_IRQ_QREGS(ENABLE_IRQ_QREGS) 212 | ) cpu 213 | ( 214 | .clk (clk), 215 | .resetn (reset_n), 216 | .mem_valid (mem_valid), 217 | .mem_instr (mem_instr), 218 | .mem_ready (mem_ready), 219 | .mem_addr (mem_addr), 220 | .mem_wdata (mem_wdata), 221 | .mem_wstrb (mem_wstrb), 222 | .mem_rdata (mem_rdata), 223 | .irq ('b0) 224 | ); 225 | 226 | endmodule // top 227 | -------------------------------------------------------------------------------- /src/mem_init0.ini: -------------------------------------------------------------------------------- 1 | 37 2 | EF 3 | 37 4 | 13 5 | 13 6 | 13 7 | 37 8 | 13 9 | 03 10 | 93 11 | B3 12 | 93 13 | 23 14 | 93 15 | E3 16 | 13 17 | 83 18 | B3 19 | B3 20 | 33 21 | 13 22 | E3 23 | 13 24 | E3 25 | 93 26 | 13 27 | 37 28 | 13 29 | 23 30 | 33 31 | 93 32 | E3 33 | 13 34 | 37 35 | 13 36 | 83 37 | B3 38 | B3 39 | 33 40 | 93 41 | 33 42 | E3 43 | 67 44 | 13 45 | 23 46 | 23 47 | 23 48 | 23 49 | 23 50 | B7 51 | 93 52 | 23 53 | 03 54 | 13 55 | 03 56 | 93 57 | 93 58 | A3 59 | 03 60 | 93 61 | 63 62 | 37 63 | 13 64 | EF 65 | 13 66 | EF 67 | 37 68 | 13 69 | EF 70 | 13 71 | EF 72 | 37 73 | 13 74 | EF 75 | 13 76 | EF 77 | 37 78 | 13 79 | EF 80 | 13 81 | EF 82 | 37 83 | 13 84 | EF 85 | 6F 86 | 93 87 | E3 88 | B7 89 | 93 90 | E3 91 | 37 92 | 13 93 | EF 94 | 13 95 | EF 96 | 37 97 | 13 98 | EF 99 | 13 100 | EF 101 | 37 102 | 13 103 | EF 104 | 13 105 | EF 106 | 37 107 | 13 108 | EF 109 | 37 110 | 13 111 | EF 112 | 37 113 | 13 114 | EF 115 | 83 116 | 03 117 | 83 118 | 03 119 | 13 120 | 67 121 | 13 122 | 23 123 | 23 124 | 23 125 | 37 126 | 13 127 | EF 128 | 13 129 | 93 130 | EF 131 | 23 132 | EF 133 | 13 134 | E3 135 | 23 136 | 37 137 | 13 138 | EF 139 | 13 140 | EF 141 | 37 142 | 13 143 | EF 144 | 83 145 | 03 146 | 83 147 | 13 148 | 67 149 | 13 150 | B7 151 | 93 152 | 23 153 | 93 154 | 23 155 | 93 156 | 23 157 | 93 158 | 23 159 | 93 160 | A3 161 | 93 162 | 23 163 | A3 164 | 13 165 | 67 166 | 13 167 | B7 168 | 93 169 | 23 170 | 83 171 | 83 172 | 83 173 | 83 174 | 83 175 | 83 176 | 83 177 | 13 178 | 67 179 | 13 180 | 23 181 | 23 182 | 13 183 | EF 184 | EF 185 | B7 186 | 63 187 | B7 188 | 63 189 | 13 190 | EF 191 | EF 192 | B7 193 | 63 194 | 37 195 | 13 196 | EF 197 | 37 198 | 13 199 | EF 200 | 6F 201 | 93 202 | 6F 203 | 37 204 | 13 205 | EF 206 | 13 207 | 6F 208 | 13 209 | EF 210 | EF 211 | 37 212 | 93 213 | E3 214 | 13 215 | 37 216 | 13 217 | EF 218 | 37 219 | 13 220 | EF 221 | 13 222 | EF 223 | 37 224 | 13 225 | EF 226 | 83 227 | 03 228 | 13 229 | 67 230 | 13 231 | 23 232 | 23 233 | 23 234 | 23 235 | 23 236 | 23 237 | 23 238 | 23 239 | 23 240 | 13 241 | EF 242 | EF 243 | EF 244 | 13 245 | EF 246 | 37 247 | 13 248 | EF 249 | 37 250 | 13 251 | EF 252 | 37 253 | 13 254 | EF 255 | B7 256 | 37 257 | B7 258 | 37 259 | B7 260 | 37 261 | 37 262 | 13 263 | 6F 264 | EF 265 | 13 266 | EF 267 | 13 268 | EF 269 | 13 270 | EF 271 | 13 272 | EF 273 | 13 274 | EF 275 | 13 276 | EF 277 | 37 278 | 13 279 | EF 280 | 37 281 | 13 282 | EF 283 | 37 284 | 13 285 | EF 286 | EF 287 | 13 288 | 13 289 | 93 290 | 63 291 | 13 292 | 33 293 | 83 294 | 67 295 | EF 296 | 6F 297 | 37 298 | 13 299 | EF 300 | 37 301 | 13 302 | EF 303 | 6F 304 | EF 305 | 93 306 | 37 307 | 13 308 | EF 309 | 13 310 | EF 311 | 37 312 | 13 313 | EF 314 | 6F 315 | EF 316 | 13 317 | 13 318 | EF 319 | 6F 320 | 37 321 | 13 322 | EF 323 | EF 324 | EF 325 | 37 326 | 13 327 | EF 328 | 6F 329 | EF 330 | 63 331 | 37 332 | 13 333 | EF 334 | 6F 335 | 37 336 | 13 337 | EF 338 | 6F 339 | 37 340 | 13 341 | EF 342 | 73 343 | EF 344 | 37 345 | 13 346 | EF 347 | 6F 348 | 37 349 | 13 350 | EF 351 | 6F 352 | B7 353 | 23 354 | 67 355 | B7 356 | A3 357 | 67 358 | B7 359 | 23 360 | 67 361 | B7 362 | A3 363 | 67 364 | B7 365 | 23 366 | 67 367 | B7 368 | 23 369 | 67 370 | B7 371 | 23 372 | 67 373 | B7 374 | 03 375 | 67 376 | B7 377 | 23 378 | 37 379 | 83 380 | E3 381 | 67 382 | 13 383 | 13 384 | B7 385 | 23 386 | 23 387 | 03 388 | 93 389 | 63 390 | 13 391 | 83 392 | 93 393 | 23 394 | 83 395 | E3 396 | 13 397 | 67 398 | 13 399 | B7 400 | 93 401 | 37 402 | 93 403 | B3 404 | 83 405 | 23 406 | 13 407 | 13 408 | E3 409 | 67 410 | 37 411 | 93 412 | 03 413 | 13 414 | E3 415 | 67 416 | B7 417 | 23 418 | 67 419 | 83 420 | 63 421 | 37 422 | 13 423 | 23 424 | 83 425 | E3 426 | 67 427 | 13 428 | 23 429 | 23 430 | 23 431 | 23 432 | 23 433 | 23 434 | 13 435 | 13 436 | 93 437 | 13 438 | B7 439 | 6F 440 | 13 441 | 33 442 | 13 443 | 23 444 | EF 445 | 93 446 | 93 447 | E3 448 | 93 449 | 93 450 | 63 451 | 93 452 | 93 453 | 63 454 | E3 455 | B7 456 | 13 457 | 23 458 | 13 459 | 83 460 | 03 461 | 83 462 | 03 463 | 83 464 | 03 465 | 13 466 | 67 467 | 13 468 | 33 469 | 13 470 | 23 471 | 6F 472 | 13 473 | 33 474 | 13 475 | 23 476 | 6F 477 | B7 478 | 23 479 | 67 480 | B7 481 | 03 482 | 13 483 | 67 484 | B7 485 | 23 486 | 67 487 | 00 488 | 00 489 | 00 490 | 00 491 | 00 492 | 00 493 | 00 494 | 00 495 | 00 496 | 00 497 | 00 498 | 00 499 | 00 500 | 00 501 | 00 502 | 00 503 | 00 504 | 00 505 | 00 506 | 00 507 | 00 508 | 00 509 | 00 510 | 00 511 | 00 512 | 00 513 | 00 514 | 00 515 | 00 516 | 00 517 | 00 518 | 00 519 | 00 520 | 00 521 | 00 522 | 00 523 | 00 524 | 00 525 | 00 526 | 00 527 | 00 528 | 00 529 | 00 530 | 00 531 | 00 532 | 00 533 | 00 534 | 00 535 | 00 536 | 00 537 | 00 538 | 00 539 | 00 540 | 00 541 | 00 542 | 00 543 | 00 544 | 00 545 | 00 546 | 00 547 | 00 548 | 00 549 | 00 550 | 00 551 | 00 552 | 00 553 | 00 554 | 00 555 | 00 556 | 00 557 | 00 558 | 00 559 | 00 560 | 00 561 | 00 562 | 00 563 | 00 564 | 00 565 | 00 566 | 00 567 | 00 568 | 00 569 | 00 570 | 00 571 | 00 572 | 00 573 | 00 574 | 00 575 | 00 576 | 00 577 | 00 578 | 00 579 | 00 580 | 00 581 | 00 582 | 00 583 | 00 584 | 00 585 | 00 586 | 00 587 | 00 588 | 00 589 | 00 590 | 00 591 | 00 592 | 00 593 | 00 594 | 00 595 | 00 596 | 00 597 | 00 598 | 00 599 | 00 600 | 00 601 | 00 602 | 00 603 | 00 604 | 00 605 | 00 606 | 00 607 | 00 608 | 00 609 | 00 610 | 00 611 | 00 612 | 00 613 | 00 614 | 00 615 | 00 616 | 00 617 | 00 618 | 00 619 | 00 620 | 00 621 | 00 622 | 00 623 | 00 624 | 00 625 | 00 626 | 00 627 | 00 628 | 00 629 | 00 630 | 00 631 | 00 632 | 00 633 | 00 634 | 00 635 | 00 636 | 00 637 | 00 638 | 00 639 | 00 640 | 00 641 | 00 642 | 00 643 | 00 644 | 00 645 | 00 646 | 00 647 | 00 648 | 00 649 | 00 650 | 00 651 | 00 652 | 00 653 | 00 654 | 00 655 | 00 656 | 00 657 | 00 658 | 00 659 | 00 660 | 00 661 | 00 662 | 00 663 | 00 664 | 00 665 | 00 666 | 00 667 | 00 668 | 00 669 | 00 670 | 00 671 | 00 672 | 00 673 | 00 674 | 00 675 | 00 676 | 00 677 | 00 678 | 00 679 | 00 680 | 00 681 | 00 682 | 00 683 | 00 684 | 00 685 | 00 686 | 00 687 | 00 688 | 00 689 | 00 690 | 00 691 | 00 692 | 00 693 | 00 694 | 00 695 | 00 696 | 00 697 | 00 698 | 00 699 | 00 700 | 00 701 | 00 702 | 00 703 | 00 704 | 00 705 | 00 706 | 00 707 | 00 708 | 00 709 | 00 710 | 00 711 | 00 712 | 00 713 | 00 714 | 00 715 | 00 716 | 00 717 | 00 718 | 00 719 | 00 720 | 00 721 | 00 722 | 00 723 | 00 724 | 00 725 | 00 726 | 00 727 | 00 728 | 00 729 | 00 730 | 00 731 | 00 732 | 00 733 | 00 734 | 00 735 | 00 736 | 00 737 | 00 738 | 00 739 | 00 740 | 00 741 | 00 742 | 00 743 | 00 744 | 00 745 | 00 746 | 00 747 | 00 748 | 00 749 | 00 750 | 00 751 | 00 752 | 00 753 | 00 754 | 00 755 | 00 756 | 00 757 | 00 758 | 00 759 | 00 760 | 00 761 | 00 762 | 00 763 | 00 764 | 00 765 | 00 766 | 00 767 | 00 768 | 00 769 | 00 770 | 00 771 | 00 772 | 00 773 | 00 774 | 00 775 | 00 776 | 00 777 | 00 778 | 00 779 | 00 780 | 00 781 | 00 782 | 00 783 | 00 784 | 00 785 | 00 786 | 00 787 | 00 788 | 00 789 | 00 790 | 00 791 | 00 792 | 00 793 | 00 794 | 00 795 | 00 796 | 00 797 | 00 798 | 00 799 | 00 800 | 00 801 | 00 802 | 00 803 | 00 804 | 00 805 | 00 806 | 00 807 | 00 808 | 00 809 | 00 810 | 00 811 | 00 812 | 00 813 | 00 814 | 00 815 | 00 816 | 00 817 | 00 818 | 00 819 | 00 820 | 00 821 | 00 822 | 00 823 | 00 824 | 00 825 | 00 826 | 00 827 | 00 828 | 00 829 | 00 830 | 00 831 | 00 832 | 00 833 | 00 834 | 00 835 | 00 836 | 00 837 | 00 838 | 00 839 | 00 840 | 00 841 | 00 842 | 00 843 | 00 844 | 00 845 | 00 846 | 00 847 | 00 848 | 00 849 | 00 850 | 00 851 | 00 852 | 00 853 | 00 854 | 00 855 | 00 856 | 00 857 | 00 858 | 00 859 | 00 860 | 00 861 | 00 862 | 00 863 | 00 864 | 00 865 | 00 866 | 00 867 | 00 868 | 00 869 | 00 870 | 00 871 | 00 872 | 00 873 | 00 874 | 00 875 | 00 876 | 00 877 | 00 878 | 00 879 | 00 880 | 00 881 | 00 882 | 00 883 | 00 884 | 00 885 | 00 886 | 00 887 | 00 888 | 00 889 | 00 890 | 00 891 | 00 892 | 00 893 | 00 894 | 00 895 | 00 896 | 00 897 | 00 898 | 00 899 | 00 900 | 00 901 | 00 902 | 00 903 | 00 904 | 00 905 | 00 906 | 00 907 | 00 908 | 00 909 | 00 910 | 00 911 | 00 912 | 00 913 | 00 914 | 00 915 | 00 916 | 00 917 | 00 918 | 00 919 | 00 920 | 00 921 | 00 922 | 00 923 | 00 924 | 00 925 | 00 926 | 00 927 | 00 928 | 00 929 | 00 930 | 00 931 | 00 932 | 00 933 | 00 934 | 00 935 | 00 936 | 00 937 | 00 938 | 00 939 | 00 940 | 00 941 | 00 942 | 00 943 | 00 944 | 00 945 | 00 946 | 00 947 | 00 948 | 00 949 | 00 950 | 00 951 | 00 952 | 00 953 | 00 954 | 00 955 | 00 956 | 00 957 | 00 958 | 00 959 | 00 960 | 00 961 | 00 962 | 00 963 | 00 964 | 00 965 | 00 966 | 00 967 | 00 968 | 00 969 | 00 970 | 00 971 | 00 972 | 00 973 | 00 974 | 00 975 | 00 976 | 00 977 | 00 978 | 00 979 | 00 980 | 00 981 | 00 982 | 00 983 | 00 984 | 00 985 | 00 986 | 00 987 | 00 988 | 00 989 | 00 990 | 00 991 | 00 992 | 00 993 | 00 994 | 00 995 | 00 996 | 00 997 | 00 998 | 00 999 | 1C 1000 | A0 1001 | 98 1002 | 6C 1003 | BC 1004 | 6C 1005 | E8 1006 | 6C 1007 | 6C 1008 | FC 1009 | 20 1010 | 6C 1011 | 6C 1012 | 6C 1013 | 6C 1014 | 48 1015 | 0D 1016 | 64 1017 | 20 1018 | 74 1019 | 74 1020 | 2C 1021 | 74 1022 | 20 1023 | 2C 1024 | 74 1025 | 20 1026 | 2C 1027 | 20 1028 | 77 1029 | 3A 1030 | 20 1031 | 53 1032 | 5D 1033 | 20 1034 | 49 1035 | 5D 1036 | 54 1037 | 20 1038 | 68 1039 | 63 1040 | 73 1041 | 68 1042 | 77 1043 | 20 1044 | 6F 1045 | 00 1046 | 0D 1047 | 52 1048 | 65 1049 | 20 1050 | 43 1051 | 74 1052 | 6E 1053 | 6D 1054 | 74 1055 | 20 1056 | 46 1057 | 45 1058 | 6D 1059 | 20 1060 | 50 1061 | 45 1062 | 00 1063 | 0D 1064 | 61 1065 | 6E 1066 | 43 1067 | 46 1068 | 3A 1069 | 00 1070 | 0D 1071 | 00 1072 | 45 1073 | 72 1074 | 6D 1075 | 64 1076 | 00 1077 | 20 1078 | 3A 1079 | 75 1080 | 6F 1081 | 74 1082 | 72 1083 | 73 1084 | 00 1085 | 20 1086 | 3A 1087 | 6C 1088 | 33 1089 | 63 1090 | 73 1091 | 20 1092 | 3A 1093 | 64 1094 | 20 1095 | 74 1096 | 20 1097 | 3A 1098 | 61 1099 | 45 1100 | 61 1101 | 0D 1102 | 20 1103 | 3A 1104 | 63 1105 | 65 1106 | 4C 1107 | 76 1108 | 65 1109 | 20 1110 | 3A 1111 | 74 1112 | 42 1113 | 44 1114 | 20 1115 | 3A 1116 | 6D 1117 | 20 1118 | 74 1119 | 20 1120 | 3A 1121 | 61 1122 | 6C 1123 | 0D 1124 | 64 1125 | 79 1126 | 6E 1127 | 00 1128 | 4C 1129 | 3D 1130 | 20 1131 | 65 1132 | 20 1133 | 20 1134 | 69 1135 | 20 1136 | 6D 1137 | 72 1138 | 65 1139 | 46 1140 | 45 1141 | 0A 1142 | 6D 1143 | 72 1144 | 65 1145 | 50 1146 | 45 1147 | 0A 1148 | 74 1149 | 20 1150 | 00 1151 | 20 1152 | 79 1153 | 61 1154 | 2E 1155 | 00 1156 | 30 1157 | 34 1158 | 38 1159 | 63 1160 | 00 1161 | 00 1162 | FF 1163 | AA 1164 | 55 1165 | EF 1166 | 00 1167 | 00 1168 | 00 1169 | -------------------------------------------------------------------------------- /src/mem_init1.ini: -------------------------------------------------------------------------------- 1 | 41 2 | 00 3 | 18 4 | 08 5 | 0E 6 | 05 7 | 13 8 | 03 9 | 26 10 | 05 11 | 86 12 | 07 13 | A0 14 | 87 15 | 9C 16 | 87 17 | 27 18 | 07 19 | 37 20 | 05 21 | 07 22 | 16 23 | 08 24 | 12 25 | 87 26 | 07 27 | 06 28 | 06 29 | A0 30 | 07 31 | 87 32 | 9A 33 | 07 34 | 06 35 | 06 36 | A7 37 | 07 38 | 37 39 | 05 40 | 85 41 | 07 42 | 94 43 | 80 44 | 01 45 | 2E 46 | 2C 47 | 2A 48 | 28 49 | 26 50 | 27 51 | 87 52 | 26 53 | 44 54 | 74 55 | 45 56 | 74 57 | 07 58 | 07 59 | 29 60 | 07 61 | 02 62 | 15 63 | 05 64 | 00 65 | 05 66 | 00 67 | 15 68 | 05 69 | 00 70 | 05 71 | 00 72 | 15 73 | 05 74 | 00 75 | 85 76 | 00 77 | 15 78 | 05 79 | 00 80 | 05 81 | 00 82 | 15 83 | 05 84 | 00 85 | 00 86 | 07 87 | 9E 88 | 27 89 | 87 90 | 18 91 | 15 92 | 05 93 | 00 94 | 05 95 | 00 96 | 15 97 | 05 98 | 00 99 | 05 100 | 00 101 | 15 102 | 05 103 | 00 104 | 05 105 | 00 106 | 15 107 | 05 108 | 00 109 | 25 110 | 05 111 | 00 112 | 15 113 | 05 114 | 00 115 | 20 116 | 24 117 | 24 118 | 29 119 | 01 120 | 80 121 | 01 122 | 2E 123 | 2C 124 | 2A 125 | 15 126 | 05 127 | 00 128 | 04 129 | 04 130 | 00 131 | 00 132 | 00 133 | 04 134 | 18 135 | 06 136 | 15 137 | 05 138 | 00 139 | 05 140 | 00 141 | 15 142 | 05 143 | 00 144 | 20 145 | 24 146 | 24 147 | 01 148 | 80 149 | 01 150 | 07 151 | 87 152 | 26 153 | 07 154 | 16 155 | 07 156 | 17 157 | 07 158 | 06 159 | 07 160 | 06 161 | 07 162 | 07 163 | 07 164 | 01 165 | 80 166 | 01 167 | 07 168 | 87 169 | 26 170 | 27 171 | 57 172 | 57 173 | 47 174 | 47 175 | 47 176 | 47 177 | 01 178 | 80 179 | 01 180 | 26 181 | 24 182 | 05 183 | 00 184 | 00 185 | 07 186 | 0C 187 | 07 188 | 68 189 | 05 190 | 00 191 | 00 192 | 07 193 | 70 194 | 15 195 | 05 196 | 00 197 | 15 198 | 05 199 | 00 200 | 00 201 | 07 202 | 00 203 | 15 204 | 05 205 | 00 206 | 04 207 | 00 208 | 05 209 | 00 210 | 00 211 | 07 212 | 07 213 | 6C 214 | E4 215 | 15 216 | 05 217 | 00 218 | 15 219 | 05 220 | 00 221 | 05 222 | 00 223 | 15 224 | 05 225 | 00 226 | 20 227 | 24 228 | 01 229 | 80 230 | 01 231 | 26 232 | 24 233 | 22 234 | 20 235 | 2E 236 | 2C 237 | 2A 238 | 28 239 | 26 240 | 05 241 | 00 242 | F0 243 | F0 244 | 05 245 | 00 246 | 15 247 | 05 248 | 00 249 | 35 250 | 05 251 | 00 252 | 15 253 | 05 254 | 00 255 | 1A 256 | 1A 257 | 19 258 | 19 259 | 14 260 | 14 261 | 1B 262 | 0B 263 | 00 264 | F0 265 | 85 266 | 00 267 | 05 268 | 00 269 | 85 270 | 00 271 | 05 272 | 00 273 | 85 274 | 00 275 | 05 276 | 00 277 | 15 278 | 05 279 | 00 280 | 15 281 | 05 282 | 00 283 | 15 284 | 05 285 | 00 286 | 00 287 | 05 288 | 77 289 | 07 290 | E4 291 | 15 292 | 05 293 | 27 294 | 80 295 | F0 296 | F0 297 | 85 298 | 05 299 | 00 300 | 15 301 | 05 302 | 00 303 | F0 304 | 00 305 | 0B 306 | 15 307 | 05 308 | 00 309 | 85 310 | 00 311 | 15 312 | 05 313 | 00 314 | F0 315 | 00 316 | 05 317 | 75 318 | 00 319 | F0 320 | 15 321 | 05 322 | 00 323 | 00 324 | 00 325 | 15 326 | 05 327 | 00 328 | F0 329 | F0 330 | 0A 331 | 15 332 | 05 333 | 00 334 | F0 335 | 15 336 | 05 337 | 00 338 | F0 339 | 15 340 | 05 341 | 00 342 | 25 343 | 00 344 | 15 345 | 05 346 | 00 347 | F0 348 | 15 349 | 05 350 | 00 351 | F0 352 | 07 353 | 88 354 | 80 355 | 07 356 | 88 357 | 80 358 | 07 359 | 89 360 | 80 361 | 07 362 | 89 363 | 80 364 | 07 365 | 98 366 | 80 367 | 07 368 | 99 369 | 80 370 | 07 371 | A8 372 | 80 373 | 07 374 | A5 375 | 80 376 | 07 377 | A8 378 | 07 379 | 27 380 | 9E 381 | 80 382 | 01 383 | 75 384 | 07 385 | 84 386 | 26 387 | 27 388 | 07 389 | CE 390 | 07 391 | 27 392 | 87 393 | 26 394 | 27 395 | 58 396 | 01 397 | 80 398 | 07 399 | 16 400 | 86 401 | 06 402 | 57 403 | 87 404 | C7 405 | 06 406 | 15 407 | 07 408 | 14 409 | 80 410 | 07 411 | 07 412 | 45 413 | 75 414 | 0C 415 | 80 416 | 07 417 | 86 418 | 80 419 | 47 420 | 8C 421 | 07 422 | 05 423 | 06 424 | 47 425 | 9A 426 | 80 427 | 01 428 | 2E 429 | 2C 430 | 2A 431 | 28 432 | 26 433 | 24 434 | 04 435 | 09 436 | 04 437 | 0A 438 | 09 439 | 00 440 | 14 441 | 04 442 | 04 443 | 86 444 | F0 445 | 07 446 | F7 447 | 72 448 | 07 449 | F7 450 | F2 451 | 07 452 | F7 453 | F6 454 | 1C 455 | 07 456 | 07 457 | 86 458 | 05 459 | 20 460 | 24 461 | 24 462 | 29 463 | 29 464 | 2A 465 | 01 466 | 80 467 | 14 468 | 04 469 | 04 470 | 86 471 | F0 472 | 14 473 | 04 474 | 04 475 | 86 476 | F0 477 | 07 478 | 80 479 | 80 480 | 07 481 | C5 482 | 75 483 | 80 484 | 07 485 | A0 486 | 80 487 | 00 488 | 00 489 | 00 490 | 00 491 | 00 492 | 00 493 | 00 494 | 00 495 | 00 496 | 00 497 | 00 498 | 00 499 | 00 500 | 00 501 | 00 502 | 00 503 | 00 504 | 00 505 | 00 506 | 00 507 | 00 508 | 00 509 | 00 510 | 00 511 | 00 512 | 00 513 | 00 514 | 00 515 | 00 516 | 00 517 | 00 518 | 00 519 | 00 520 | 00 521 | 00 522 | 00 523 | 00 524 | 00 525 | 00 526 | 00 527 | 00 528 | 00 529 | 00 530 | 00 531 | 00 532 | 00 533 | 00 534 | 00 535 | 00 536 | 00 537 | 00 538 | 00 539 | 00 540 | 00 541 | 00 542 | 00 543 | 00 544 | 00 545 | 00 546 | 00 547 | 00 548 | 00 549 | 00 550 | 00 551 | 00 552 | 00 553 | 00 554 | 00 555 | 00 556 | 00 557 | 00 558 | 00 559 | 00 560 | 00 561 | 00 562 | 00 563 | 00 564 | 00 565 | 00 566 | 00 567 | 00 568 | 00 569 | 00 570 | 00 571 | 00 572 | 00 573 | 00 574 | 00 575 | 00 576 | 00 577 | 00 578 | 00 579 | 00 580 | 00 581 | 00 582 | 00 583 | 00 584 | 00 585 | 00 586 | 00 587 | 00 588 | 00 589 | 00 590 | 00 591 | 00 592 | 00 593 | 00 594 | 00 595 | 00 596 | 00 597 | 00 598 | 00 599 | 00 600 | 00 601 | 00 602 | 00 603 | 00 604 | 00 605 | 00 606 | 00 607 | 00 608 | 00 609 | 00 610 | 00 611 | 00 612 | 00 613 | 00 614 | 00 615 | 00 616 | 00 617 | 00 618 | 00 619 | 00 620 | 00 621 | 00 622 | 00 623 | 00 624 | 00 625 | 00 626 | 00 627 | 00 628 | 00 629 | 00 630 | 00 631 | 00 632 | 00 633 | 00 634 | 00 635 | 00 636 | 00 637 | 00 638 | 00 639 | 00 640 | 00 641 | 00 642 | 00 643 | 00 644 | 00 645 | 00 646 | 00 647 | 00 648 | 00 649 | 00 650 | 00 651 | 00 652 | 00 653 | 00 654 | 00 655 | 00 656 | 00 657 | 00 658 | 00 659 | 00 660 | 00 661 | 00 662 | 00 663 | 00 664 | 00 665 | 00 666 | 00 667 | 00 668 | 00 669 | 00 670 | 00 671 | 00 672 | 00 673 | 00 674 | 00 675 | 00 676 | 00 677 | 00 678 | 00 679 | 00 680 | 00 681 | 00 682 | 00 683 | 00 684 | 00 685 | 00 686 | 00 687 | 00 688 | 00 689 | 00 690 | 00 691 | 00 692 | 00 693 | 00 694 | 00 695 | 00 696 | 00 697 | 00 698 | 00 699 | 00 700 | 00 701 | 00 702 | 00 703 | 00 704 | 00 705 | 00 706 | 00 707 | 00 708 | 00 709 | 00 710 | 00 711 | 00 712 | 00 713 | 00 714 | 00 715 | 00 716 | 00 717 | 00 718 | 00 719 | 00 720 | 00 721 | 00 722 | 00 723 | 00 724 | 00 725 | 00 726 | 00 727 | 00 728 | 00 729 | 00 730 | 00 731 | 00 732 | 00 733 | 00 734 | 00 735 | 00 736 | 00 737 | 00 738 | 00 739 | 00 740 | 00 741 | 00 742 | 00 743 | 00 744 | 00 745 | 00 746 | 00 747 | 00 748 | 00 749 | 00 750 | 00 751 | 00 752 | 00 753 | 00 754 | 00 755 | 00 756 | 00 757 | 00 758 | 00 759 | 00 760 | 00 761 | 00 762 | 00 763 | 00 764 | 00 765 | 00 766 | 00 767 | 00 768 | 00 769 | 00 770 | 00 771 | 00 772 | 00 773 | 00 774 | 00 775 | 00 776 | 00 777 | 00 778 | 00 779 | 00 780 | 00 781 | 00 782 | 00 783 | 00 784 | 00 785 | 00 786 | 00 787 | 00 788 | 00 789 | 00 790 | 00 791 | 00 792 | 00 793 | 00 794 | 00 795 | 00 796 | 00 797 | 00 798 | 00 799 | 00 800 | 00 801 | 00 802 | 00 803 | 00 804 | 00 805 | 00 806 | 00 807 | 00 808 | 00 809 | 00 810 | 00 811 | 00 812 | 00 813 | 00 814 | 00 815 | 00 816 | 00 817 | 00 818 | 00 819 | 00 820 | 00 821 | 00 822 | 00 823 | 00 824 | 00 825 | 00 826 | 00 827 | 00 828 | 00 829 | 00 830 | 00 831 | 00 832 | 00 833 | 00 834 | 00 835 | 00 836 | 00 837 | 00 838 | 00 839 | 00 840 | 00 841 | 00 842 | 00 843 | 00 844 | 00 845 | 00 846 | 00 847 | 00 848 | 00 849 | 00 850 | 00 851 | 00 852 | 00 853 | 00 854 | 00 855 | 00 856 | 00 857 | 00 858 | 00 859 | 00 860 | 00 861 | 00 862 | 00 863 | 00 864 | 00 865 | 00 866 | 00 867 | 00 868 | 00 869 | 00 870 | 00 871 | 00 872 | 00 873 | 00 874 | 00 875 | 00 876 | 00 877 | 00 878 | 00 879 | 00 880 | 00 881 | 00 882 | 00 883 | 00 884 | 00 885 | 00 886 | 00 887 | 00 888 | 00 889 | 00 890 | 00 891 | 00 892 | 00 893 | 00 894 | 00 895 | 00 896 | 00 897 | 00 898 | 00 899 | 00 900 | 00 901 | 00 902 | 00 903 | 00 904 | 00 905 | 00 906 | 00 907 | 00 908 | 00 909 | 00 910 | 00 911 | 00 912 | 00 913 | 00 914 | 00 915 | 00 916 | 00 917 | 00 918 | 00 919 | 00 920 | 00 921 | 00 922 | 00 923 | 00 924 | 00 925 | 00 926 | 00 927 | 00 928 | 00 929 | 00 930 | 00 931 | 00 932 | 00 933 | 00 934 | 00 935 | 00 936 | 00 937 | 00 938 | 00 939 | 00 940 | 00 941 | 00 942 | 00 943 | 00 944 | 00 945 | 00 946 | 00 947 | 00 948 | 00 949 | 00 950 | 00 951 | 00 952 | 00 953 | 00 954 | 00 955 | 00 956 | 00 957 | 00 958 | 00 959 | 00 960 | 00 961 | 00 962 | 00 963 | 00 964 | 00 965 | 00 966 | 00 967 | 00 968 | 00 969 | 00 970 | 00 971 | 00 972 | 00 973 | 00 974 | 00 975 | 00 976 | 00 977 | 00 978 | 00 979 | 00 980 | 00 981 | 00 982 | 00 983 | 00 984 | 00 985 | 00 986 | 00 987 | 00 988 | 00 989 | 00 990 | 00 991 | 00 992 | 00 993 | 00 994 | 00 995 | 00 996 | 00 997 | 00 998 | 00 999 | 04 1000 | 04 1001 | 04 1002 | 05 1003 | 04 1004 | 05 1005 | 04 1006 | 05 1007 | 05 1008 | 04 1009 | 05 1010 | 05 1011 | 05 1012 | 05 1013 | 05 1014 | 05 1015 | 0A 1016 | 69 1017 | 74 1018 | 3A 1019 | 20 1020 | 20 1021 | 65 1022 | 00 1023 | 20 1024 | 65 1025 | 00 1026 | 0D 1027 | 20 1028 | 6F 1029 | 20 1030 | 5B 1031 | 53 1032 | 0D 1033 | 5B 1034 | 4C 1035 | 0D 1036 | 79 1037 | 34 1038 | 61 1039 | 74 1040 | 20 1041 | 65 1042 | 69 1043 | 65 1044 | 29 1045 | 00 1046 | 0A 1047 | 54 1048 | 61 1049 | 00 1050 | 6F 1051 | 64 1052 | 20 1053 | 65 1054 | 65 1055 | 00 1056 | 41 1057 | 44 1058 | 61 1059 | 3D 1060 | 41 1061 | 44 1062 | 00 1063 | 0A 1064 | 72 1065 | 67 1066 | 4C 1067 | 52 1068 | 20 1069 | 00 1070 | 0A 1071 | 00 1072 | 6E 1073 | 20 1074 | 6D 1075 | 3A 1076 | 00 1077 | 20 1078 | 20 1079 | 6E 1080 | 77 1081 | 69 1082 | 20 1083 | 74 1084 | 00 1085 | 20 1086 | 20 1087 | 61 1088 | 20 1089 | 6F 1090 | 0D 1091 | 20 1092 | 20 1093 | 69 1094 | 74 1095 | 0D 1096 | 20 1097 | 20 1098 | 64 1099 | 44 1100 | 6C 1101 | 0A 1102 | 20 1103 | 20 1104 | 72 1105 | 6E 1106 | 45 1107 | 61 1108 | 0D 1109 | 20 1110 | 20 1111 | 20 1112 | 20 1113 | 0D 1114 | 20 1115 | 20 1116 | 6F 1117 | 74 1118 | 0D 1119 | 20 1120 | 20 1121 | 64 1122 | 6F 1123 | 0A 1124 | 65 1125 | 20 1126 | 65 1127 | 00 1128 | 45 1129 | 20 1130 | 65 1131 | 72 1132 | 68 1133 | 64 1134 | 74 1135 | 00 1136 | 65 1137 | 79 1138 | 73 1139 | 41 1140 | 44 1141 | 00 1142 | 65 1143 | 79 1144 | 73 1145 | 41 1146 | 44 1147 | 00 1148 | 69 1149 | 69 1150 | 00 1151 | 20 1152 | 20 1153 | 69 1154 | 2E 1155 | 00 1156 | 31 1157 | 35 1158 | 39 1159 | 64 1160 | 00 1161 | 00 1162 | FF 1163 | AA 1164 | 55 1165 | BE 1166 | 00 1167 | 00 1168 | 00 1169 | -------------------------------------------------------------------------------- /src/mem_init2.ini: -------------------------------------------------------------------------------- 1 | 00 2 | 00 3 | 00 4 | 08 5 | 48 6 | 00 7 | 00 8 | 03 9 | 08 10 | 80 11 | 65 12 | 80 13 | C7 14 | 47 15 | D7 16 | 05 17 | 07 18 | F6 19 | F0 20 | F5 21 | 47 22 | D7 23 | 48 24 | C8 25 | 05 26 | 00 27 | 02 28 | 16 29 | E7 30 | C7 31 | 47 32 | D7 33 | 00 34 | 02 35 | 16 36 | 05 37 | F7 38 | F0 39 | F5 40 | 45 41 | C7 42 | D5 43 | 00 44 | 01 45 | 11 46 | 81 47 | 91 48 | 21 49 | 01 50 | 33 51 | 17 52 | F1 53 | C1 54 | F4 55 | F1 56 | F5 57 | B0 58 | F1 59 | C1 60 | 10 61 | F4 62 | 00 63 | 85 64 | C0 65 | C1 66 | 00 67 | 00 68 | C5 69 | 80 70 | 04 71 | C0 72 | 00 73 | 85 74 | 40 75 | 04 76 | 80 77 | 00 78 | 45 79 | 00 80 | 09 81 | 40 82 | 00 83 | 05 84 | C0 85 | 80 86 | 40 87 | F4 88 | 33 89 | 17 90 | F9 91 | 00 92 | 85 93 | 80 94 | C1 95 | C0 96 | 00 97 | C5 98 | 40 99 | 10 100 | 80 101 | 00 102 | 85 103 | 00 104 | 40 105 | 40 106 | 00 107 | 45 108 | C0 109 | 33 110 | 15 111 | C0 112 | 00 113 | 45 114 | 40 115 | C1 116 | 81 117 | 41 118 | 01 119 | 01 120 | 00 121 | 01 122 | 11 123 | 81 124 | 91 125 | 00 126 | C5 127 | 00 128 | 81 129 | C1 130 | 00 131 | A4 132 | 00 133 | 14 134 | 94 135 | 01 136 | 00 137 | 45 138 | 40 139 | 81 140 | C0 141 | 00 142 | 05 143 | 00 144 | C1 145 | 81 146 | 41 147 | 01 148 | 00 149 | 01 150 | 02 151 | 07 152 | F1 153 | 20 154 | F1 155 | 00 156 | F1 157 | 30 158 | F1 159 | 20 160 | F1 161 | 10 162 | F1 163 | 01 164 | 01 165 | 00 166 | 01 167 | 02 168 | 07 169 | F1 170 | C1 171 | C1 172 | E1 173 | C1 174 | D1 175 | E1 176 | F1 177 | 01 178 | 00 179 | 01 180 | 11 181 | 81 182 | F0 183 | 80 184 | 40 185 | 00 186 | F5 187 | 00 188 | F5 189 | 00 190 | 40 191 | 80 192 | 01 193 | F5 194 | 00 195 | 45 196 | C0 197 | 00 198 | C5 199 | 00 200 | 80 201 | 00 202 | 00 203 | 00 204 | 45 205 | 80 206 | 10 207 | C0 208 | 00 209 | 80 210 | C0 211 | 01 212 | 10 213 | E5 214 | 27 215 | 00 216 | 45 217 | 80 218 | 00 219 | C5 220 | C0 221 | 04 222 | 00 223 | 00 224 | 05 225 | 80 226 | C1 227 | 81 228 | 01 229 | 00 230 | 01 231 | 11 232 | 81 233 | 91 234 | 21 235 | 31 236 | 41 237 | 51 238 | 61 239 | 71 240 | 60 241 | 00 242 | DF 243 | DF 244 | E0 245 | 40 246 | 00 247 | 85 248 | C0 249 | 31 250 | 05 251 | C0 252 | 00 253 | 45 254 | 40 255 | 00 256 | 00 257 | 00 258 | 00 259 | 00 260 | 00 261 | 00 262 | 8B 263 | 80 264 | DF 265 | CA 266 | 40 267 | 0A 268 | C0 269 | 09 270 | 40 271 | 89 272 | C0 273 | C4 274 | 40 275 | 44 276 | C0 277 | 00 278 | 05 279 | 00 280 | 00 281 | 45 282 | 40 283 | 00 284 | 85 285 | 80 286 | 00 287 | D5 288 | F5 289 | F0 290 | E7 291 | 27 292 | 65 293 | 05 294 | 07 295 | 5F 296 | 5F 297 | 93 298 | 05 299 | 40 300 | 00 301 | C5 302 | 40 303 | 9F 304 | 00 305 | 05 306 | 00 307 | C5 308 | C0 309 | 0B 310 | 00 311 | 00 312 | 05 313 | 80 314 | DF 315 | 40 316 | 15 317 | F5 318 | C0 319 | 9F 320 | 00 321 | 45 322 | 40 323 | 00 324 | 00 325 | 00 326 | 05 327 | 00 328 | 5F 329 | 9F 330 | 05 331 | 00 332 | C5 333 | 80 334 | DF 335 | 00 336 | 45 337 | 80 338 | DF 339 | 00 340 | C5 341 | 80 342 | 10 343 | C0 344 | 00 345 | 05 346 | 40 347 | 9F 348 | 00 349 | 85 350 | 40 351 | 9F 352 | 00 353 | A7 354 | 00 355 | 00 356 | A7 357 | 00 358 | 00 359 | A7 360 | 00 361 | 00 362 | A7 363 | 00 364 | 00 365 | A7 366 | 00 367 | 00 368 | A7 369 | 00 370 | 00 371 | A7 372 | 00 373 | 00 374 | 07 375 | 00 376 | 00 377 | A7 378 | 00 379 | 07 380 | 07 381 | 00 382 | 01 383 | F5 384 | 00 385 | A7 386 | 01 387 | C1 388 | 70 389 | E7 390 | 70 391 | C1 392 | 17 393 | F1 394 | C1 395 | F7 396 | 01 397 | 00 398 | 80 399 | 00 400 | C6 401 | 00 402 | C5 403 | F6 404 | 07 405 | F6 406 | 45 407 | F7 408 | 07 409 | 00 410 | 00 411 | F0 412 | C7 413 | F5 414 | F5 415 | 00 416 | 00 417 | A7 418 | 00 419 | 05 420 | 07 421 | 00 422 | 15 423 | F7 424 | 05 425 | 07 426 | 00 427 | 01 428 | 11 429 | 81 430 | 91 431 | 21 432 | 31 433 | 41 434 | 00 435 | 90 436 | 50 437 | D0 438 | 00 439 | 40 440 | 44 441 | A4 442 | 04 443 | A9 444 | 9F 445 | 05 446 | F7 447 | F9 448 | F5 449 | F7 450 | F4 451 | F5 452 | F7 453 | F4 454 | 45 455 | 00 456 | A0 457 | E7 458 | 04 459 | C1 460 | 81 461 | 41 462 | 01 463 | C1 464 | 81 465 | 01 466 | 00 467 | 44 468 | A4 469 | 94 470 | A9 471 | 5F 472 | 44 473 | A4 474 | 94 475 | A9 476 | 1F 477 | 00 478 | A7 479 | 00 480 | 00 481 | 07 482 | F5 483 | 00 484 | 00 485 | A7 486 | 00 487 | 00 488 | 00 489 | 00 490 | 00 491 | 00 492 | 00 493 | 00 494 | 00 495 | 00 496 | 00 497 | 00 498 | 00 499 | 00 500 | 00 501 | 00 502 | 00 503 | 00 504 | 00 505 | 00 506 | 00 507 | 00 508 | 00 509 | 00 510 | 00 511 | 00 512 | 00 513 | 00 514 | 00 515 | 00 516 | 00 517 | 00 518 | 00 519 | 00 520 | 00 521 | 00 522 | 00 523 | 00 524 | 00 525 | 00 526 | 00 527 | 00 528 | 00 529 | 00 530 | 00 531 | 00 532 | 00 533 | 00 534 | 00 535 | 00 536 | 00 537 | 00 538 | 00 539 | 00 540 | 00 541 | 00 542 | 00 543 | 00 544 | 00 545 | 00 546 | 00 547 | 00 548 | 00 549 | 00 550 | 00 551 | 00 552 | 00 553 | 00 554 | 00 555 | 00 556 | 00 557 | 00 558 | 00 559 | 00 560 | 00 561 | 00 562 | 00 563 | 00 564 | 00 565 | 00 566 | 00 567 | 00 568 | 00 569 | 00 570 | 00 571 | 00 572 | 00 573 | 00 574 | 00 575 | 00 576 | 00 577 | 00 578 | 00 579 | 00 580 | 00 581 | 00 582 | 00 583 | 00 584 | 00 585 | 00 586 | 00 587 | 00 588 | 00 589 | 00 590 | 00 591 | 00 592 | 00 593 | 00 594 | 00 595 | 00 596 | 00 597 | 00 598 | 00 599 | 00 600 | 00 601 | 00 602 | 00 603 | 00 604 | 00 605 | 00 606 | 00 607 | 00 608 | 00 609 | 00 610 | 00 611 | 00 612 | 00 613 | 00 614 | 00 615 | 00 616 | 00 617 | 00 618 | 00 619 | 00 620 | 00 621 | 00 622 | 00 623 | 00 624 | 00 625 | 00 626 | 00 627 | 00 628 | 00 629 | 00 630 | 00 631 | 00 632 | 00 633 | 00 634 | 00 635 | 00 636 | 00 637 | 00 638 | 00 639 | 00 640 | 00 641 | 00 642 | 00 643 | 00 644 | 00 645 | 00 646 | 00 647 | 00 648 | 00 649 | 00 650 | 00 651 | 00 652 | 00 653 | 00 654 | 00 655 | 00 656 | 00 657 | 00 658 | 00 659 | 00 660 | 00 661 | 00 662 | 00 663 | 00 664 | 00 665 | 00 666 | 00 667 | 00 668 | 00 669 | 00 670 | 00 671 | 00 672 | 00 673 | 00 674 | 00 675 | 00 676 | 00 677 | 00 678 | 00 679 | 00 680 | 00 681 | 00 682 | 00 683 | 00 684 | 00 685 | 00 686 | 00 687 | 00 688 | 00 689 | 00 690 | 00 691 | 00 692 | 00 693 | 00 694 | 00 695 | 00 696 | 00 697 | 00 698 | 00 699 | 00 700 | 00 701 | 00 702 | 00 703 | 00 704 | 00 705 | 00 706 | 00 707 | 00 708 | 00 709 | 00 710 | 00 711 | 00 712 | 00 713 | 00 714 | 00 715 | 00 716 | 00 717 | 00 718 | 00 719 | 00 720 | 00 721 | 00 722 | 00 723 | 00 724 | 00 725 | 00 726 | 00 727 | 00 728 | 00 729 | 00 730 | 00 731 | 00 732 | 00 733 | 00 734 | 00 735 | 00 736 | 00 737 | 00 738 | 00 739 | 00 740 | 00 741 | 00 742 | 00 743 | 00 744 | 00 745 | 00 746 | 00 747 | 00 748 | 00 749 | 00 750 | 00 751 | 00 752 | 00 753 | 00 754 | 00 755 | 00 756 | 00 757 | 00 758 | 00 759 | 00 760 | 00 761 | 00 762 | 00 763 | 00 764 | 00 765 | 00 766 | 00 767 | 00 768 | 00 769 | 00 770 | 00 771 | 00 772 | 00 773 | 00 774 | 00 775 | 00 776 | 00 777 | 00 778 | 00 779 | 00 780 | 00 781 | 00 782 | 00 783 | 00 784 | 00 785 | 00 786 | 00 787 | 00 788 | 00 789 | 00 790 | 00 791 | 00 792 | 00 793 | 00 794 | 00 795 | 00 796 | 00 797 | 00 798 | 00 799 | 00 800 | 00 801 | 00 802 | 00 803 | 00 804 | 00 805 | 00 806 | 00 807 | 00 808 | 00 809 | 00 810 | 00 811 | 00 812 | 00 813 | 00 814 | 00 815 | 00 816 | 00 817 | 00 818 | 00 819 | 00 820 | 00 821 | 00 822 | 00 823 | 00 824 | 00 825 | 00 826 | 00 827 | 00 828 | 00 829 | 00 830 | 00 831 | 00 832 | 00 833 | 00 834 | 00 835 | 00 836 | 00 837 | 00 838 | 00 839 | 00 840 | 00 841 | 00 842 | 00 843 | 00 844 | 00 845 | 00 846 | 00 847 | 00 848 | 00 849 | 00 850 | 00 851 | 00 852 | 00 853 | 00 854 | 00 855 | 00 856 | 00 857 | 00 858 | 00 859 | 00 860 | 00 861 | 00 862 | 00 863 | 00 864 | 00 865 | 00 866 | 00 867 | 00 868 | 00 869 | 00 870 | 00 871 | 00 872 | 00 873 | 00 874 | 00 875 | 00 876 | 00 877 | 00 878 | 00 879 | 00 880 | 00 881 | 00 882 | 00 883 | 00 884 | 00 885 | 00 886 | 00 887 | 00 888 | 00 889 | 00 890 | 00 891 | 00 892 | 00 893 | 00 894 | 00 895 | 00 896 | 00 897 | 00 898 | 00 899 | 00 900 | 00 901 | 00 902 | 00 903 | 00 904 | 00 905 | 00 906 | 00 907 | 00 908 | 00 909 | 00 910 | 00 911 | 00 912 | 00 913 | 00 914 | 00 915 | 00 916 | 00 917 | 00 918 | 00 919 | 00 920 | 00 921 | 00 922 | 00 923 | 00 924 | 00 925 | 00 926 | 00 927 | 00 928 | 00 929 | 00 930 | 00 931 | 00 932 | 00 933 | 00 934 | 00 935 | 00 936 | 00 937 | 00 938 | 00 939 | 00 940 | 00 941 | 00 942 | 00 943 | 00 944 | 00 945 | 00 946 | 00 947 | 00 948 | 00 949 | 00 950 | 00 951 | 00 952 | 00 953 | 00 954 | 00 955 | 00 956 | 00 957 | 00 958 | 00 959 | 00 960 | 00 961 | 00 962 | 00 963 | 00 964 | 00 965 | 00 966 | 00 967 | 00 968 | 00 969 | 00 970 | 00 971 | 00 972 | 00 973 | 00 974 | 00 975 | 00 976 | 00 977 | 00 978 | 00 979 | 00 980 | 00 981 | 00 982 | 00 983 | 00 984 | 00 985 | 00 986 | 00 987 | 00 988 | 00 989 | 00 990 | 00 991 | 00 992 | 00 993 | 00 994 | 00 995 | 00 996 | 00 997 | 00 998 | 00 999 | 00 1000 | 00 1001 | 00 1002 | 00 1003 | 00 1004 | 00 1005 | 00 1006 | 00 1007 | 00 1008 | 00 1009 | 00 1010 | 00 1011 | 00 1012 | 00 1013 | 00 1014 | 00 1015 | 45 1016 | 61 1017 | 65 1018 | 20 1019 | 00 1020 | 62 1021 | 30 1022 | 00 1023 | 62 1024 | 33 1025 | 00 1026 | 0A 1027 | 20 1028 | 72 1029 | 00 1030 | 50 1031 | 45 1032 | 0A 1033 | 46 1034 | 45 1035 | 0A 1036 | 70 1037 | 20 1038 | 72 1039 | 65 1040 | 28 1041 | 79 1042 | 6C 1043 | 63 1044 | 3A 1045 | 00 1046 | 55 1047 | 20 1048 | 64 1049 | 00 1050 | 75 1051 | 6F 1052 | 74 1053 | 72 1054 | 73 1055 | 00 1056 | 49 1057 | 2C 1058 | 73 1059 | 20 1060 | 53 1061 | 0D 1062 | 00 1063 | 53 1064 | 74 1065 | 2C 1066 | 4B 1067 | 45 1068 | 30 1069 | 00 1070 | 0D 1071 | 00 1072 | 74 1073 | 63 1074 | 61 1075 | 0D 1076 | 00 1077 | 20 1078 | 63 1079 | 74 1080 | 6E 1081 | 6D 1082 | 74 1083 | 0D 1084 | 00 1085 | 20 1086 | 64 1087 | 79 1088 | 73 1089 | 6E 1090 | 0A 1091 | 20 1092 | 65 1093 | 61 1094 | 65 1095 | 0A 1096 | 20 1097 | 72 1098 | 20 1099 | 20 1100 | 75 1101 | 00 1102 | 20 1103 | 69 1104 | 65 1105 | 74 1106 | 44 1107 | 6C 1108 | 0A 1109 | 20 1110 | 73 1111 | 52 1112 | 4C 1113 | 0A 1114 | 20 1115 | 6D 1116 | 72 1117 | 65 1118 | 0A 1119 | 20 1120 | 72 1121 | 20 1122 | 63 1123 | 00 1124 | 6C 1125 | 64 1126 | 0D 1127 | 00 1128 | 44 1129 | 00 1130 | 6E 1131 | 20 1132 | 65 1133 | 69 1134 | 73 1135 | 00 1136 | 6D 1137 | 20 1138 | 74 1139 | 49 1140 | 2E 1141 | 00 1142 | 6D 1143 | 20 1144 | 74 1145 | 53 1146 | 2E 1147 | 00 1148 | 6D 1149 | 73 1150 | 00 1151 | 54 1152 | 61 1153 | 6E 1154 | 0D 1155 | 00 1156 | 32 1157 | 36 1158 | 61 1159 | 65 1160 | 00 1161 | 00 1162 | FF 1163 | AA 1164 | 55 1165 | AD 1166 | 00 1167 | 00 1168 | 00 1169 | -------------------------------------------------------------------------------- /src/mem_init3.ini: -------------------------------------------------------------------------------- 1 | 00 2 | 39 3 | 00 4 | 22 5 | 01 6 | 00 7 | 00 8 | 80 9 | 00 10 | 79 11 | 00 12 | 79 13 | 00 14 | 00 15 | FE 16 | 00 17 | 00 18 | 40 19 | 00 20 | 00 21 | 00 22 | FE 23 | 00 24 | FD 25 | 00 26 | 00 27 | 00 28 | 00 29 | 00 30 | 00 31 | 00 32 | FE 33 | 00 34 | 00 35 | 00 36 | 00 37 | 40 38 | 00 39 | 00 40 | 00 41 | 00 42 | FE 43 | 00 44 | FE 45 | 00 46 | 00 47 | 00 48 | 01 49 | 00 50 | 44 51 | 21 52 | 00 53 | 00 54 | 0F 55 | 00 56 | 0F 57 | FA 58 | 00 59 | 00 60 | 01 61 | 06 62 | 00 63 | FD 64 | 58 65 | 00 66 | 53 67 | 00 68 | FE 69 | 57 70 | 00 71 | 51 72 | 00 73 | FF 74 | 56 75 | 00 76 | 50 77 | 00 78 | 00 79 | 55 80 | 00 81 | 4F 82 | 00 83 | 02 84 | 53 85 | 07 86 | 04 87 | F8 88 | AB 89 | 21 90 | F8 91 | 00 92 | FD 93 | 51 94 | 00 95 | 4B 96 | 00 97 | FE 98 | 50 99 | 01 100 | 4A 101 | 00 102 | FF 103 | 4F 104 | 04 105 | 49 106 | 00 107 | 00 108 | 4D 109 | AB 110 | 21 111 | 47 112 | 00 113 | 01 114 | 4C 115 | 01 116 | 01 117 | 01 118 | 01 119 | 02 120 | 00 121 | FE 122 | 00 123 | 00 124 | 00 125 | 00 126 | 02 127 | 49 128 | 00 129 | 00 130 | 46 131 | 00 132 | 47 133 | 00 134 | FE 135 | 00 136 | 00 137 | 05 138 | 46 139 | 00 140 | 45 141 | 00 142 | 13 143 | 45 144 | 01 145 | 01 146 | 01 147 | 02 148 | 00 149 | FF 150 | 03 151 | 10 152 | 00 153 | 30 154 | 00 155 | 10 156 | 00 157 | 00 158 | 00 159 | 00 160 | 00 161 | 00 162 | 00 163 | 00 164 | 01 165 | 00 166 | FF 167 | 03 168 | 10 169 | 00 170 | 00 171 | 00 172 | 00 173 | 00 174 | 00 175 | 00 176 | 00 177 | 01 178 | 00 179 | FF 180 | 00 181 | 00 182 | 0F 183 | 2C 184 | 2F 185 | FF 186 | 04 187 | FE 188 | 04 189 | 00 190 | 2C 191 | 2D 192 | 00 193 | 02 194 | 00 195 | 06 196 | 37 197 | 00 198 | 08 199 | 37 200 | 06 201 | 00 202 | 03 203 | 00 204 | 06 205 | 35 206 | 00 207 | 02 208 | 00 209 | 27 210 | 28 211 | 00 212 | 00 213 | FC 214 | 00 215 | 00 216 | 06 217 | 32 218 | 00 219 | 07 220 | 31 221 | 00 222 | 2C 223 | 00 224 | 13 225 | 30 226 | 00 227 | 00 228 | 01 229 | 00 230 | FD 231 | 02 232 | 02 233 | 02 234 | 03 235 | 01 236 | 01 237 | 01 238 | 01 239 | 01 240 | 00 241 | 3B 242 | E8 243 | EC 244 | 0A 245 | 22 246 | 00 247 | 09 248 | 2A 249 | 01 250 | D0 251 | 24 252 | 00 253 | 0B 254 | 29 255 | 00 256 | 00 257 | 00 258 | 00 259 | 00 260 | 00 261 | 00 262 | F9 263 | 00 264 | EA 265 | 0B 266 | 26 267 | 0D 268 | 25 269 | 0F 270 | 25 271 | 10 272 | 24 273 | 11 274 | 24 275 | 13 276 | 23 277 | 00 278 | 15 279 | 23 280 | 00 281 | 16 282 | 22 283 | 00 284 | 17 285 | 21 286 | 1F 287 | F9 288 | 0F 289 | 00 290 | 0E 291 | 00 292 | 01 293 | 00 294 | 00 295 | C1 296 | F8 297 | 03 298 | 70 299 | 13 300 | 00 301 | 18 302 | 1D 303 | F6 304 | 2C 305 | 00 306 | 00 307 | 19 308 | 1B 309 | 00 310 | 16 311 | 00 312 | 13 313 | 1A 314 | F3 315 | 29 316 | 00 317 | 0F 318 | 27 319 | F2 320 | 00 321 | 1A 322 | 18 323 | 1A 324 | 28 325 | 00 326 | 13 327 | 17 328 | F0 329 | AE 330 | 00 331 | 00 332 | 1B 333 | 15 334 | EE 335 | 00 336 | 1D 337 | 14 338 | ED 339 | 00 340 | 1E 341 | 13 342 | C0 343 | 0D 344 | 00 345 | 13 346 | 12 347 | EB 348 | 00 349 | 1F 350 | 11 351 | EA 352 | 80 353 | 00 354 | 00 355 | 80 356 | 00 357 | 00 358 | 80 359 | 00 360 | 00 361 | 80 362 | 00 363 | 00 364 | 80 365 | 00 366 | 00 367 | 80 368 | 00 369 | 00 370 | 80 371 | 00 372 | 00 373 | 80 374 | 01 375 | 00 376 | 80 377 | 00 378 | 80 379 | 01 380 | FE 381 | 00 382 | FF 383 | 0F 384 | 80 385 | 00 386 | 00 387 | 00 388 | 0C 389 | 00 390 | 0C 391 | 00 392 | 00 393 | 00 394 | 00 395 | FE 396 | 01 397 | 00 398 | 00 399 | 00 400 | 20 401 | 80 402 | 01 403 | 00 404 | 00 405 | 00 406 | 00 407 | FF 408 | FE 409 | 00 410 | 80 411 | 0F 412 | 00 413 | 0F 414 | FE 415 | 00 416 | 80 417 | 00 418 | 00 419 | 00 420 | 00 421 | 80 422 | 00 423 | 00 424 | 00 425 | FE 426 | 00 427 | FE 428 | 00 429 | 00 430 | 00 431 | 01 432 | 01 433 | 01 434 | 00 435 | 00 436 | 00 437 | 00 438 | 80 439 | 01 440 | 00 441 | 00 442 | FD 443 | 00 444 | F7 445 | FD 446 | 0F 447 | FE 448 | F9 449 | 0F 450 | 04 451 | FB 452 | 0F 453 | 04 454 | FD 455 | 80 456 | 00 457 | 00 458 | 00 459 | 01 460 | 01 461 | 01 462 | 01 463 | 00 464 | 00 465 | 02 466 | 00 467 | 00 468 | 00 469 | FA 470 | 00 471 | F9 472 | 00 473 | 00 474 | FC 475 | 00 476 | F8 477 | 80 478 | 00 479 | 00 480 | 80 481 | 00 482 | 0F 483 | 00 484 | 80 485 | 02 486 | 00 487 | 00 488 | 00 489 | 00 490 | 00 491 | 00 492 | 00 493 | 00 494 | 00 495 | 00 496 | 00 497 | 00 498 | 00 499 | 00 500 | 00 501 | 00 502 | 00 503 | 00 504 | 00 505 | 00 506 | 00 507 | 00 508 | 00 509 | 00 510 | 00 511 | 00 512 | 00 513 | 00 514 | 00 515 | 00 516 | 00 517 | 00 518 | 00 519 | 00 520 | 00 521 | 00 522 | 00 523 | 00 524 | 00 525 | 00 526 | 00 527 | 00 528 | 00 529 | 00 530 | 00 531 | 00 532 | 00 533 | 00 534 | 00 535 | 00 536 | 00 537 | 00 538 | 00 539 | 00 540 | 00 541 | 00 542 | 00 543 | 00 544 | 00 545 | 00 546 | 00 547 | 00 548 | 00 549 | 00 550 | 00 551 | 00 552 | 00 553 | 00 554 | 00 555 | 00 556 | 00 557 | 00 558 | 00 559 | 00 560 | 00 561 | 00 562 | 00 563 | 00 564 | 00 565 | 00 566 | 00 567 | 00 568 | 00 569 | 00 570 | 00 571 | 00 572 | 00 573 | 00 574 | 00 575 | 00 576 | 00 577 | 00 578 | 00 579 | 00 580 | 00 581 | 00 582 | 00 583 | 00 584 | 00 585 | 00 586 | 00 587 | 00 588 | 00 589 | 00 590 | 00 591 | 00 592 | 00 593 | 00 594 | 00 595 | 00 596 | 00 597 | 00 598 | 00 599 | 00 600 | 00 601 | 00 602 | 00 603 | 00 604 | 00 605 | 00 606 | 00 607 | 00 608 | 00 609 | 00 610 | 00 611 | 00 612 | 00 613 | 00 614 | 00 615 | 00 616 | 00 617 | 00 618 | 00 619 | 00 620 | 00 621 | 00 622 | 00 623 | 00 624 | 00 625 | 00 626 | 00 627 | 00 628 | 00 629 | 00 630 | 00 631 | 00 632 | 00 633 | 00 634 | 00 635 | 00 636 | 00 637 | 00 638 | 00 639 | 00 640 | 00 641 | 00 642 | 00 643 | 00 644 | 00 645 | 00 646 | 00 647 | 00 648 | 00 649 | 00 650 | 00 651 | 00 652 | 00 653 | 00 654 | 00 655 | 00 656 | 00 657 | 00 658 | 00 659 | 00 660 | 00 661 | 00 662 | 00 663 | 00 664 | 00 665 | 00 666 | 00 667 | 00 668 | 00 669 | 00 670 | 00 671 | 00 672 | 00 673 | 00 674 | 00 675 | 00 676 | 00 677 | 00 678 | 00 679 | 00 680 | 00 681 | 00 682 | 00 683 | 00 684 | 00 685 | 00 686 | 00 687 | 00 688 | 00 689 | 00 690 | 00 691 | 00 692 | 00 693 | 00 694 | 00 695 | 00 696 | 00 697 | 00 698 | 00 699 | 00 700 | 00 701 | 00 702 | 00 703 | 00 704 | 00 705 | 00 706 | 00 707 | 00 708 | 00 709 | 00 710 | 00 711 | 00 712 | 00 713 | 00 714 | 00 715 | 00 716 | 00 717 | 00 718 | 00 719 | 00 720 | 00 721 | 00 722 | 00 723 | 00 724 | 00 725 | 00 726 | 00 727 | 00 728 | 00 729 | 00 730 | 00 731 | 00 732 | 00 733 | 00 734 | 00 735 | 00 736 | 00 737 | 00 738 | 00 739 | 00 740 | 00 741 | 00 742 | 00 743 | 00 744 | 00 745 | 00 746 | 00 747 | 00 748 | 00 749 | 00 750 | 00 751 | 00 752 | 00 753 | 00 754 | 00 755 | 00 756 | 00 757 | 00 758 | 00 759 | 00 760 | 00 761 | 00 762 | 00 763 | 00 764 | 00 765 | 00 766 | 00 767 | 00 768 | 00 769 | 00 770 | 00 771 | 00 772 | 00 773 | 00 774 | 00 775 | 00 776 | 00 777 | 00 778 | 00 779 | 00 780 | 00 781 | 00 782 | 00 783 | 00 784 | 00 785 | 00 786 | 00 787 | 00 788 | 00 789 | 00 790 | 00 791 | 00 792 | 00 793 | 00 794 | 00 795 | 00 796 | 00 797 | 00 798 | 00 799 | 00 800 | 00 801 | 00 802 | 00 803 | 00 804 | 00 805 | 00 806 | 00 807 | 00 808 | 00 809 | 00 810 | 00 811 | 00 812 | 00 813 | 00 814 | 00 815 | 00 816 | 00 817 | 00 818 | 00 819 | 00 820 | 00 821 | 00 822 | 00 823 | 00 824 | 00 825 | 00 826 | 00 827 | 00 828 | 00 829 | 00 830 | 00 831 | 00 832 | 00 833 | 00 834 | 00 835 | 00 836 | 00 837 | 00 838 | 00 839 | 00 840 | 00 841 | 00 842 | 00 843 | 00 844 | 00 845 | 00 846 | 00 847 | 00 848 | 00 849 | 00 850 | 00 851 | 00 852 | 00 853 | 00 854 | 00 855 | 00 856 | 00 857 | 00 858 | 00 859 | 00 860 | 00 861 | 00 862 | 00 863 | 00 864 | 00 865 | 00 866 | 00 867 | 00 868 | 00 869 | 00 870 | 00 871 | 00 872 | 00 873 | 00 874 | 00 875 | 00 876 | 00 877 | 00 878 | 00 879 | 00 880 | 00 881 | 00 882 | 00 883 | 00 884 | 00 885 | 00 886 | 00 887 | 00 888 | 00 889 | 00 890 | 00 891 | 00 892 | 00 893 | 00 894 | 00 895 | 00 896 | 00 897 | 00 898 | 00 899 | 00 900 | 00 901 | 00 902 | 00 903 | 00 904 | 00 905 | 00 906 | 00 907 | 00 908 | 00 909 | 00 910 | 00 911 | 00 912 | 00 913 | 00 914 | 00 915 | 00 916 | 00 917 | 00 918 | 00 919 | 00 920 | 00 921 | 00 922 | 00 923 | 00 924 | 00 925 | 00 926 | 00 927 | 00 928 | 00 929 | 00 930 | 00 931 | 00 932 | 00 933 | 00 934 | 00 935 | 00 936 | 00 937 | 00 938 | 00 939 | 00 940 | 00 941 | 00 942 | 00 943 | 00 944 | 00 945 | 00 946 | 00 947 | 00 948 | 00 949 | 00 950 | 00 951 | 00 952 | 00 953 | 00 954 | 00 955 | 00 956 | 00 957 | 00 958 | 00 959 | 00 960 | 00 961 | 00 962 | 00 963 | 00 964 | 00 965 | 00 966 | 00 967 | 00 968 | 00 969 | 00 970 | 00 971 | 00 972 | 00 973 | 00 974 | 00 975 | 00 976 | 00 977 | 00 978 | 00 979 | 00 980 | 00 981 | 00 982 | 00 983 | 00 984 | 00 985 | 00 986 | 00 987 | 00 988 | 00 989 | 00 990 | 00 991 | 00 992 | 00 993 | 00 994 | 00 995 | 00 996 | 00 997 | 00 998 | 00 999 | 00 1000 | 00 1001 | 00 1002 | 00 1003 | 00 1004 | 00 1005 | 00 1006 | 00 1007 | 00 1008 | 00 1009 | 00 1010 | 00 1011 | 00 1012 | 00 1013 | 00 1014 | 00 1015 | 6E 1016 | 6E 1017 | 73 1018 | 61 1019 | 00 1020 | 79 1021 | 3A 1022 | 00 1023 | 79 1024 | 3A 1025 | 00 1026 | 20 1027 | 20 1028 | 64 1029 | 00 1030 | 41 1031 | 44 1032 | 00 1033 | 41 1034 | 44 1035 | 00 1036 | 65 1037 | 63 1038 | 61 1039 | 72 1040 | 74 1041 | 20 1042 | 6C 1043 | 68 1044 | 20 1045 | 00 1046 | 41 1047 | 72 1048 | 3A 1049 | 00 1050 | 6E 1051 | 77 1052 | 69 1053 | 20 1054 | 74 1055 | 00 1056 | 4C 1057 | 20 1058 | 6B 1059 | 00 1060 | 53 1061 | 0A 1062 | 00 1063 | 74 1064 | 69 1065 | 20 1066 | 5F 1067 | 51 1068 | 78 1069 | 00 1070 | 0A 1071 | 00 1072 | 65 1073 | 6F 1074 | 6E 1075 | 0A 1076 | 00 1077 | 63 1078 | 6F 1079 | 64 1080 | 20 1081 | 65 1082 | 65 1083 | 0A 1084 | 00 1085 | 64 1086 | 65 1087 | 20 1088 | 65 1089 | 64 1090 | 00 1091 | 65 1092 | 6E 1093 | 6E 1094 | 73 1095 | 00 1096 | 67 1097 | 65 1098 | 4C 1099 | 76 1100 | 65 1101 | 00 1102 | 69 1103 | 6E 1104 | 6D 1105 | 20 1106 | 20 1107 | 75 1108 | 00 1109 | 6C 1110 | 65 1111 | 47 1112 | 45 1113 | 00 1114 | 6D 1115 | 65 1116 | 79 1117 | 73 1118 | 00 1119 | 72 1120 | 65 1121 | 63 1122 | 6B 1123 | 00 1124 | 61 1125 | 6F 1126 | 0A 1127 | 00 1128 | 20 1129 | 00 1130 | 74 1131 | 36 1132 | 78 1133 | 67 1134 | 3A 1135 | 00 1136 | 6F 1137 | 74 1138 | 20 1139 | 4C 1140 | 0D 1141 | 00 1142 | 6F 1143 | 74 1144 | 20 1145 | 53 1146 | 0D 1147 | 00 1148 | 65 1149 | 20 1150 | 00 1151 | 72 1152 | 67 1153 | 2E 1154 | 0A 1155 | 00 1156 | 33 1157 | 37 1158 | 62 1159 | 66 1160 | 00 1161 | 00 1162 | FF 1163 | AA 1164 | 55 1165 | DE 1166 | 00 1167 | 00 1168 | 00 1169 | -------------------------------------------------------------------------------- /src/picorv32.v: -------------------------------------------------------------------------------- 1 | /* 2 | * PicoRV32 -- A Small RISC-V (RV32I) Processor Core 3 | * 4 | * Copyright (C) 2015 Claire Xenia Wolf 5 | * 6 | * Permission to use, copy, modify, and/or distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | * 18 | */ 19 | 20 | /* verilator lint_off WIDTH */ 21 | /* verilator lint_off PINMISSING */ 22 | /* verilator lint_off CASEOVERLAP */ 23 | /* verilator lint_off CASEINCOMPLETE */ 24 | 25 | `timescale 1 ns / 1 ps 26 | // `default_nettype none 27 | // `define DEBUGNETS 28 | // `define DEBUGREGS 29 | // `define DEBUGASM 30 | // `define DEBUG 31 | 32 | `ifdef DEBUG 33 | `define debug(debug_command) debug_command 34 | `else 35 | `define debug(debug_command) 36 | `endif 37 | 38 | `ifdef FORMAL 39 | `define FORMAL_KEEP (* keep *) 40 | `define assert(assert_expr) assert(assert_expr) 41 | `else 42 | `ifdef DEBUGNETS 43 | `define FORMAL_KEEP (* keep *) 44 | `else 45 | `define FORMAL_KEEP 46 | `endif 47 | `define assert(assert_expr) empty_statement 48 | `endif 49 | 50 | // uncomment this for register file in extra module 51 | // `define PICORV32_REGS picorv32_regs 52 | 53 | // this macro can be used to check if the verilog files in your 54 | // design are read in the correct order. 55 | `define PICORV32_V 56 | 57 | 58 | /*************************************************************** 59 | * picorv32 60 | ***************************************************************/ 61 | 62 | module picorv32 #( 63 | parameter [ 0:0] ENABLE_COUNTERS = 1, 64 | parameter [ 0:0] ENABLE_COUNTERS64 = 1, 65 | parameter [ 0:0] ENABLE_REGS_16_31 = 1, 66 | parameter [ 0:0] ENABLE_REGS_DUALPORT = 1, 67 | parameter [ 0:0] LATCHED_MEM_RDATA = 0, 68 | parameter [ 0:0] TWO_STAGE_SHIFT = 1, 69 | parameter [ 0:0] BARREL_SHIFTER = 0, 70 | parameter [ 0:0] TWO_CYCLE_COMPARE = 0, 71 | parameter [ 0:0] TWO_CYCLE_ALU = 0, 72 | parameter [ 0:0] COMPRESSED_ISA = 0, 73 | parameter [ 0:0] CATCH_MISALIGN = 1, 74 | parameter [ 0:0] CATCH_ILLINSN = 1, 75 | parameter [ 0:0] ENABLE_PCPI = 0, 76 | parameter [ 0:0] ENABLE_MUL = 0, 77 | parameter [ 0:0] ENABLE_FAST_MUL = 0, 78 | parameter [ 0:0] ENABLE_DIV = 0, 79 | parameter [ 0:0] ENABLE_IRQ = 0, 80 | parameter [ 0:0] ENABLE_IRQ_QREGS = 1, 81 | parameter [ 0:0] ENABLE_IRQ_TIMER = 1, 82 | parameter [ 0:0] ENABLE_TRACE = 0, 83 | parameter [ 0:0] REGS_INIT_ZERO = 0, 84 | parameter [31:0] MASKED_IRQ = 32'h0000_0000, 85 | parameter [31:0] LATCHED_IRQ = 32'hffff_ffff, 86 | parameter [31:0] PROGADDR_RESET = 32'h0000_0000, 87 | parameter [31:0] PROGADDR_IRQ = 32'h0000_0000, 88 | parameter [31:0] STACKADDR = 32'hffff_ffff 89 | ) ( 90 | input clk, resetn, 91 | output reg trap, 92 | 93 | output reg mem_valid, 94 | output reg mem_instr, 95 | input mem_ready, 96 | 97 | output reg [31:0] mem_addr, 98 | output reg [31:0] mem_wdata, 99 | output reg [ 3:0] mem_wstrb, 100 | input [31:0] mem_rdata, 101 | 102 | // Look-Ahead Interface 103 | output mem_la_read, 104 | output mem_la_write, 105 | output [31:0] mem_la_addr, 106 | output reg [31:0] mem_la_wdata, 107 | output reg [ 3:0] mem_la_wstrb, 108 | 109 | // Pico Co-Processor Interface (PCPI) 110 | output reg pcpi_valid, 111 | output reg [31:0] pcpi_insn, 112 | output [31:0] pcpi_rs1, 113 | output [31:0] pcpi_rs2, 114 | input pcpi_wr, 115 | input [31:0] pcpi_rd, 116 | input pcpi_wait, 117 | input pcpi_ready, 118 | 119 | // IRQ Interface 120 | input [31:0] irq, 121 | output reg [31:0] eoi, 122 | 123 | `ifdef RISCV_FORMAL 124 | output reg rvfi_valid, 125 | output reg [63:0] rvfi_order, 126 | output reg [31:0] rvfi_insn, 127 | output reg rvfi_trap, 128 | output reg rvfi_halt, 129 | output reg rvfi_intr, 130 | output reg [ 1:0] rvfi_mode, 131 | output reg [ 1:0] rvfi_ixl, 132 | output reg [ 4:0] rvfi_rs1_addr, 133 | output reg [ 4:0] rvfi_rs2_addr, 134 | output reg [31:0] rvfi_rs1_rdata, 135 | output reg [31:0] rvfi_rs2_rdata, 136 | output reg [ 4:0] rvfi_rd_addr, 137 | output reg [31:0] rvfi_rd_wdata, 138 | output reg [31:0] rvfi_pc_rdata, 139 | output reg [31:0] rvfi_pc_wdata, 140 | output reg [31:0] rvfi_mem_addr, 141 | output reg [ 3:0] rvfi_mem_rmask, 142 | output reg [ 3:0] rvfi_mem_wmask, 143 | output reg [31:0] rvfi_mem_rdata, 144 | output reg [31:0] rvfi_mem_wdata, 145 | 146 | output reg [63:0] rvfi_csr_mcycle_rmask, 147 | output reg [63:0] rvfi_csr_mcycle_wmask, 148 | output reg [63:0] rvfi_csr_mcycle_rdata, 149 | output reg [63:0] rvfi_csr_mcycle_wdata, 150 | 151 | output reg [63:0] rvfi_csr_minstret_rmask, 152 | output reg [63:0] rvfi_csr_minstret_wmask, 153 | output reg [63:0] rvfi_csr_minstret_rdata, 154 | output reg [63:0] rvfi_csr_minstret_wdata, 155 | `endif 156 | 157 | // Trace Interface 158 | output reg trace_valid, 159 | output reg [35:0] trace_data 160 | ); 161 | localparam integer irq_timer = 0; 162 | localparam integer irq_ebreak = 1; 163 | localparam integer irq_buserror = 2; 164 | 165 | localparam integer irqregs_offset = ENABLE_REGS_16_31 ? 32 : 16; 166 | localparam integer regfile_size = (ENABLE_REGS_16_31 ? 32 : 16) + 4*ENABLE_IRQ*ENABLE_IRQ_QREGS; 167 | localparam integer regindex_bits = (ENABLE_REGS_16_31 ? 5 : 4) + ENABLE_IRQ*ENABLE_IRQ_QREGS; 168 | 169 | localparam WITH_PCPI = ENABLE_PCPI || ENABLE_MUL || ENABLE_FAST_MUL || ENABLE_DIV; 170 | 171 | localparam [35:0] TRACE_BRANCH = {4'b 0001, 32'b 0}; 172 | localparam [35:0] TRACE_ADDR = {4'b 0010, 32'b 0}; 173 | localparam [35:0] TRACE_IRQ = {4'b 1000, 32'b 0}; 174 | 175 | reg [63:0] count_cycle, count_instr; 176 | reg [31:0] reg_pc, reg_next_pc, reg_op1, reg_op2, reg_out; 177 | reg [4:0] reg_sh; 178 | 179 | reg [31:0] next_insn_opcode; 180 | reg [31:0] dbg_insn_opcode; 181 | reg [31:0] dbg_insn_addr; 182 | 183 | wire dbg_mem_valid = mem_valid; 184 | wire dbg_mem_instr = mem_instr; 185 | wire dbg_mem_ready = mem_ready; 186 | wire [31:0] dbg_mem_addr = mem_addr; 187 | wire [31:0] dbg_mem_wdata = mem_wdata; 188 | wire [ 3:0] dbg_mem_wstrb = mem_wstrb; 189 | wire [31:0] dbg_mem_rdata = mem_rdata; 190 | 191 | assign pcpi_rs1 = reg_op1; 192 | assign pcpi_rs2 = reg_op2; 193 | 194 | wire [31:0] next_pc; 195 | 196 | reg irq_delay; 197 | reg irq_active; 198 | reg [31:0] irq_mask; 199 | reg [31:0] irq_pending; 200 | reg [31:0] timer; 201 | 202 | `ifndef PICORV32_REGS 203 | reg [31:0] cpuregs [0:regfile_size-1]; 204 | 205 | integer i; 206 | initial begin 207 | if (REGS_INIT_ZERO) begin 208 | for (i = 0; i < regfile_size; i = i+1) 209 | cpuregs[i] = 0; 210 | end 211 | end 212 | `endif 213 | 214 | task empty_statement; 215 | // This task is used by the `assert directive in non-formal mode to 216 | // avoid empty statement (which are unsupported by plain Verilog syntax). 217 | begin end 218 | endtask 219 | 220 | `ifdef DEBUGREGS 221 | wire [31:0] dbg_reg_x0 = 0; 222 | wire [31:0] dbg_reg_x1 = cpuregs[1]; 223 | wire [31:0] dbg_reg_x2 = cpuregs[2]; 224 | wire [31:0] dbg_reg_x3 = cpuregs[3]; 225 | wire [31:0] dbg_reg_x4 = cpuregs[4]; 226 | wire [31:0] dbg_reg_x5 = cpuregs[5]; 227 | wire [31:0] dbg_reg_x6 = cpuregs[6]; 228 | wire [31:0] dbg_reg_x7 = cpuregs[7]; 229 | wire [31:0] dbg_reg_x8 = cpuregs[8]; 230 | wire [31:0] dbg_reg_x9 = cpuregs[9]; 231 | wire [31:0] dbg_reg_x10 = cpuregs[10]; 232 | wire [31:0] dbg_reg_x11 = cpuregs[11]; 233 | wire [31:0] dbg_reg_x12 = cpuregs[12]; 234 | wire [31:0] dbg_reg_x13 = cpuregs[13]; 235 | wire [31:0] dbg_reg_x14 = cpuregs[14]; 236 | wire [31:0] dbg_reg_x15 = cpuregs[15]; 237 | wire [31:0] dbg_reg_x16 = cpuregs[16]; 238 | wire [31:0] dbg_reg_x17 = cpuregs[17]; 239 | wire [31:0] dbg_reg_x18 = cpuregs[18]; 240 | wire [31:0] dbg_reg_x19 = cpuregs[19]; 241 | wire [31:0] dbg_reg_x20 = cpuregs[20]; 242 | wire [31:0] dbg_reg_x21 = cpuregs[21]; 243 | wire [31:0] dbg_reg_x22 = cpuregs[22]; 244 | wire [31:0] dbg_reg_x23 = cpuregs[23]; 245 | wire [31:0] dbg_reg_x24 = cpuregs[24]; 246 | wire [31:0] dbg_reg_x25 = cpuregs[25]; 247 | wire [31:0] dbg_reg_x26 = cpuregs[26]; 248 | wire [31:0] dbg_reg_x27 = cpuregs[27]; 249 | wire [31:0] dbg_reg_x28 = cpuregs[28]; 250 | wire [31:0] dbg_reg_x29 = cpuregs[29]; 251 | wire [31:0] dbg_reg_x30 = cpuregs[30]; 252 | wire [31:0] dbg_reg_x31 = cpuregs[31]; 253 | `endif 254 | 255 | // Internal PCPI Cores 256 | 257 | wire pcpi_mul_wr; 258 | wire [31:0] pcpi_mul_rd; 259 | wire pcpi_mul_wait; 260 | wire pcpi_mul_ready; 261 | 262 | wire pcpi_div_wr; 263 | wire [31:0] pcpi_div_rd; 264 | wire pcpi_div_wait; 265 | wire pcpi_div_ready; 266 | 267 | reg pcpi_int_wr; 268 | reg [31:0] pcpi_int_rd; 269 | reg pcpi_int_wait; 270 | reg pcpi_int_ready; 271 | 272 | generate if (ENABLE_FAST_MUL) begin 273 | picorv32_pcpi_fast_mul pcpi_mul ( 274 | .clk (clk ), 275 | .resetn (resetn ), 276 | .pcpi_valid(pcpi_valid ), 277 | .pcpi_insn (pcpi_insn ), 278 | .pcpi_rs1 (pcpi_rs1 ), 279 | .pcpi_rs2 (pcpi_rs2 ), 280 | .pcpi_wr (pcpi_mul_wr ), 281 | .pcpi_rd (pcpi_mul_rd ), 282 | .pcpi_wait (pcpi_mul_wait ), 283 | .pcpi_ready(pcpi_mul_ready ) 284 | ); 285 | end else if (ENABLE_MUL) begin 286 | picorv32_pcpi_mul pcpi_mul ( 287 | .clk (clk ), 288 | .resetn (resetn ), 289 | .pcpi_valid(pcpi_valid ), 290 | .pcpi_insn (pcpi_insn ), 291 | .pcpi_rs1 (pcpi_rs1 ), 292 | .pcpi_rs2 (pcpi_rs2 ), 293 | .pcpi_wr (pcpi_mul_wr ), 294 | .pcpi_rd (pcpi_mul_rd ), 295 | .pcpi_wait (pcpi_mul_wait ), 296 | .pcpi_ready(pcpi_mul_ready ) 297 | ); 298 | end else begin 299 | assign pcpi_mul_wr = 0; 300 | assign pcpi_mul_rd = 32'bx; 301 | assign pcpi_mul_wait = 0; 302 | assign pcpi_mul_ready = 0; 303 | end endgenerate 304 | 305 | generate if (ENABLE_DIV) begin 306 | picorv32_pcpi_div pcpi_div ( 307 | .clk (clk ), 308 | .resetn (resetn ), 309 | .pcpi_valid(pcpi_valid ), 310 | .pcpi_insn (pcpi_insn ), 311 | .pcpi_rs1 (pcpi_rs1 ), 312 | .pcpi_rs2 (pcpi_rs2 ), 313 | .pcpi_wr (pcpi_div_wr ), 314 | .pcpi_rd (pcpi_div_rd ), 315 | .pcpi_wait (pcpi_div_wait ), 316 | .pcpi_ready(pcpi_div_ready ) 317 | ); 318 | end else begin 319 | assign pcpi_div_wr = 0; 320 | assign pcpi_div_rd = 32'bx; 321 | assign pcpi_div_wait = 0; 322 | assign pcpi_div_ready = 0; 323 | end endgenerate 324 | 325 | always @* begin 326 | pcpi_int_wr = 0; 327 | pcpi_int_rd = 32'bx; 328 | pcpi_int_wait = |{ENABLE_PCPI && pcpi_wait, (ENABLE_MUL || ENABLE_FAST_MUL) && pcpi_mul_wait, ENABLE_DIV && pcpi_div_wait}; 329 | pcpi_int_ready = |{ENABLE_PCPI && pcpi_ready, (ENABLE_MUL || ENABLE_FAST_MUL) && pcpi_mul_ready, ENABLE_DIV && pcpi_div_ready}; 330 | 331 | (* parallel_case *) 332 | case (1'b1) 333 | ENABLE_PCPI && pcpi_ready: begin 334 | pcpi_int_wr = ENABLE_PCPI ? pcpi_wr : 0; 335 | pcpi_int_rd = ENABLE_PCPI ? pcpi_rd : 0; 336 | end 337 | (ENABLE_MUL || ENABLE_FAST_MUL) && pcpi_mul_ready: begin 338 | pcpi_int_wr = pcpi_mul_wr; 339 | pcpi_int_rd = pcpi_mul_rd; 340 | end 341 | ENABLE_DIV && pcpi_div_ready: begin 342 | pcpi_int_wr = pcpi_div_wr; 343 | pcpi_int_rd = pcpi_div_rd; 344 | end 345 | endcase 346 | end 347 | 348 | 349 | // Memory Interface 350 | 351 | reg [1:0] mem_state; 352 | reg [1:0] mem_wordsize; 353 | reg [31:0] mem_rdata_word; 354 | reg [31:0] mem_rdata_q; 355 | reg mem_do_prefetch; 356 | reg mem_do_rinst; 357 | reg mem_do_rdata; 358 | reg mem_do_wdata; 359 | 360 | wire mem_xfer; 361 | reg mem_la_secondword, mem_la_firstword_reg, last_mem_valid; 362 | wire mem_la_firstword = COMPRESSED_ISA && (mem_do_prefetch || mem_do_rinst) && next_pc[1] && !mem_la_secondword; 363 | wire mem_la_firstword_xfer = COMPRESSED_ISA && mem_xfer && (!last_mem_valid ? mem_la_firstword : mem_la_firstword_reg); 364 | 365 | reg prefetched_high_word; 366 | reg clear_prefetched_high_word; 367 | reg [15:0] mem_16bit_buffer; 368 | 369 | wire [31:0] mem_rdata_latched_noshuffle; 370 | wire [31:0] mem_rdata_latched; 371 | 372 | wire mem_la_use_prefetched_high_word = COMPRESSED_ISA && mem_la_firstword && prefetched_high_word && !clear_prefetched_high_word; 373 | assign mem_xfer = (mem_valid && mem_ready) || (mem_la_use_prefetched_high_word && mem_do_rinst); 374 | 375 | wire mem_busy = |{mem_do_prefetch, mem_do_rinst, mem_do_rdata, mem_do_wdata}; 376 | wire mem_done = resetn && ((mem_xfer && |mem_state && (mem_do_rinst || mem_do_rdata || mem_do_wdata)) || (&mem_state && mem_do_rinst)) && 377 | (!mem_la_firstword || (~&mem_rdata_latched[1:0] && mem_xfer)); 378 | 379 | assign mem_la_write = resetn && !mem_state && mem_do_wdata; 380 | assign mem_la_read = resetn && ((!mem_la_use_prefetched_high_word && !mem_state && (mem_do_rinst || mem_do_prefetch || mem_do_rdata)) || 381 | (COMPRESSED_ISA && mem_xfer && (!last_mem_valid ? mem_la_firstword : mem_la_firstword_reg) && !mem_la_secondword && &mem_rdata_latched[1:0])); 382 | assign mem_la_addr = (mem_do_prefetch || mem_do_rinst) ? {next_pc[31:2] + mem_la_firstword_xfer, 2'b00} : {reg_op1[31:2], 2'b00}; 383 | 384 | assign mem_rdata_latched_noshuffle = (mem_xfer || LATCHED_MEM_RDATA) ? mem_rdata : mem_rdata_q; 385 | 386 | assign mem_rdata_latched = COMPRESSED_ISA && mem_la_use_prefetched_high_word ? {16'bx, mem_16bit_buffer} : 387 | COMPRESSED_ISA && mem_la_secondword ? {mem_rdata_latched_noshuffle[15:0], mem_16bit_buffer} : 388 | COMPRESSED_ISA && mem_la_firstword ? {16'bx, mem_rdata_latched_noshuffle[31:16]} : mem_rdata_latched_noshuffle; 389 | 390 | always @(posedge clk) begin 391 | if (!resetn) begin 392 | mem_la_firstword_reg <= 0; 393 | last_mem_valid <= 0; 394 | end else begin 395 | if (!last_mem_valid) 396 | mem_la_firstword_reg <= mem_la_firstword; 397 | last_mem_valid <= mem_valid && !mem_ready; 398 | end 399 | end 400 | 401 | always @* begin 402 | (* full_case *) 403 | case (mem_wordsize) 404 | 0: begin 405 | mem_la_wdata = reg_op2; 406 | mem_la_wstrb = 4'b1111; 407 | mem_rdata_word = mem_rdata; 408 | end 409 | 1: begin 410 | mem_la_wdata = {2{reg_op2[15:0]}}; 411 | mem_la_wstrb = reg_op1[1] ? 4'b1100 : 4'b0011; 412 | case (reg_op1[1]) 413 | 1'b0: mem_rdata_word = {16'b0, mem_rdata[15: 0]}; 414 | 1'b1: mem_rdata_word = {16'b0, mem_rdata[31:16]}; 415 | endcase 416 | end 417 | 2: begin 418 | mem_la_wdata = {4{reg_op2[7:0]}}; 419 | mem_la_wstrb = 4'b0001 << reg_op1[1:0]; 420 | case (reg_op1[1:0]) 421 | 2'b00: mem_rdata_word = {24'b0, mem_rdata[ 7: 0]}; 422 | 2'b01: mem_rdata_word = {24'b0, mem_rdata[15: 8]}; 423 | 2'b10: mem_rdata_word = {24'b0, mem_rdata[23:16]}; 424 | 2'b11: mem_rdata_word = {24'b0, mem_rdata[31:24]}; 425 | endcase 426 | end 427 | endcase 428 | end 429 | 430 | always @(posedge clk) begin 431 | if (mem_xfer) begin 432 | mem_rdata_q <= COMPRESSED_ISA ? mem_rdata_latched : mem_rdata; 433 | next_insn_opcode <= COMPRESSED_ISA ? mem_rdata_latched : mem_rdata; 434 | end 435 | 436 | if (COMPRESSED_ISA && mem_done && (mem_do_prefetch || mem_do_rinst)) begin 437 | case (mem_rdata_latched[1:0]) 438 | 2'b00: begin // Quadrant 0 439 | case (mem_rdata_latched[15:13]) 440 | 3'b000: begin // C.ADDI4SPN 441 | mem_rdata_q[14:12] <= 3'b000; 442 | mem_rdata_q[31:20] <= {2'b0, mem_rdata_latched[10:7], mem_rdata_latched[12:11], mem_rdata_latched[5], mem_rdata_latched[6], 2'b00}; 443 | end 444 | 3'b010: begin // C.LW 445 | mem_rdata_q[31:20] <= {5'b0, mem_rdata_latched[5], mem_rdata_latched[12:10], mem_rdata_latched[6], 2'b00}; 446 | mem_rdata_q[14:12] <= 3'b 010; 447 | end 448 | 3'b 110: begin // C.SW 449 | {mem_rdata_q[31:25], mem_rdata_q[11:7]} <= {5'b0, mem_rdata_latched[5], mem_rdata_latched[12:10], mem_rdata_latched[6], 2'b00}; 450 | mem_rdata_q[14:12] <= 3'b 010; 451 | end 452 | endcase 453 | end 454 | 2'b01: begin // Quadrant 1 455 | case (mem_rdata_latched[15:13]) 456 | 3'b 000: begin // C.ADDI 457 | mem_rdata_q[14:12] <= 3'b000; 458 | mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]}); 459 | end 460 | 3'b 010: begin // C.LI 461 | mem_rdata_q[14:12] <= 3'b000; 462 | mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]}); 463 | end 464 | 3'b 011: begin 465 | if (mem_rdata_latched[11:7] == 2) begin // C.ADDI16SP 466 | mem_rdata_q[14:12] <= 3'b000; 467 | mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[4:3], 468 | mem_rdata_latched[5], mem_rdata_latched[2], mem_rdata_latched[6], 4'b 0000}); 469 | end else begin // C.LUI 470 | mem_rdata_q[31:12] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]}); 471 | end 472 | end 473 | 3'b100: begin 474 | if (mem_rdata_latched[11:10] == 2'b00) begin // C.SRLI 475 | mem_rdata_q[31:25] <= 7'b0000000; 476 | mem_rdata_q[14:12] <= 3'b 101; 477 | end 478 | if (mem_rdata_latched[11:10] == 2'b01) begin // C.SRAI 479 | mem_rdata_q[31:25] <= 7'b0100000; 480 | mem_rdata_q[14:12] <= 3'b 101; 481 | end 482 | if (mem_rdata_latched[11:10] == 2'b10) begin // C.ANDI 483 | mem_rdata_q[14:12] <= 3'b111; 484 | mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]}); 485 | end 486 | if (mem_rdata_latched[12:10] == 3'b011) begin // C.SUB, C.XOR, C.OR, C.AND 487 | if (mem_rdata_latched[6:5] == 2'b00) mem_rdata_q[14:12] <= 3'b000; 488 | if (mem_rdata_latched[6:5] == 2'b01) mem_rdata_q[14:12] <= 3'b100; 489 | if (mem_rdata_latched[6:5] == 2'b10) mem_rdata_q[14:12] <= 3'b110; 490 | if (mem_rdata_latched[6:5] == 2'b11) mem_rdata_q[14:12] <= 3'b111; 491 | mem_rdata_q[31:25] <= mem_rdata_latched[6:5] == 2'b00 ? 7'b0100000 : 7'b0000000; 492 | end 493 | end 494 | 3'b 110: begin // C.BEQZ 495 | mem_rdata_q[14:12] <= 3'b000; 496 | { mem_rdata_q[31], mem_rdata_q[7], mem_rdata_q[30:25], mem_rdata_q[11:8] } <= 497 | $signed({mem_rdata_latched[12], mem_rdata_latched[6:5], mem_rdata_latched[2], 498 | mem_rdata_latched[11:10], mem_rdata_latched[4:3]}); 499 | end 500 | 3'b 111: begin // C.BNEZ 501 | mem_rdata_q[14:12] <= 3'b001; 502 | { mem_rdata_q[31], mem_rdata_q[7], mem_rdata_q[30:25], mem_rdata_q[11:8] } <= 503 | $signed({mem_rdata_latched[12], mem_rdata_latched[6:5], mem_rdata_latched[2], 504 | mem_rdata_latched[11:10], mem_rdata_latched[4:3]}); 505 | end 506 | endcase 507 | end 508 | 2'b10: begin // Quadrant 2 509 | case (mem_rdata_latched[15:13]) 510 | 3'b000: begin // C.SLLI 511 | mem_rdata_q[31:25] <= 7'b0000000; 512 | mem_rdata_q[14:12] <= 3'b 001; 513 | end 514 | 3'b010: begin // C.LWSP 515 | mem_rdata_q[31:20] <= {4'b0, mem_rdata_latched[3:2], mem_rdata_latched[12], mem_rdata_latched[6:4], 2'b00}; 516 | mem_rdata_q[14:12] <= 3'b 010; 517 | end 518 | 3'b100: begin 519 | if (mem_rdata_latched[12] == 0 && mem_rdata_latched[6:2] == 0) begin // C.JR 520 | mem_rdata_q[14:12] <= 3'b000; 521 | mem_rdata_q[31:20] <= 12'b0; 522 | end 523 | if (mem_rdata_latched[12] == 0 && mem_rdata_latched[6:2] != 0) begin // C.MV 524 | mem_rdata_q[14:12] <= 3'b000; 525 | mem_rdata_q[31:25] <= 7'b0000000; 526 | end 527 | if (mem_rdata_latched[12] != 0 && mem_rdata_latched[11:7] != 0 && mem_rdata_latched[6:2] == 0) begin // C.JALR 528 | mem_rdata_q[14:12] <= 3'b000; 529 | mem_rdata_q[31:20] <= 12'b0; 530 | end 531 | if (mem_rdata_latched[12] != 0 && mem_rdata_latched[6:2] != 0) begin // C.ADD 532 | mem_rdata_q[14:12] <= 3'b000; 533 | mem_rdata_q[31:25] <= 7'b0000000; 534 | end 535 | end 536 | 3'b110: begin // C.SWSP 537 | {mem_rdata_q[31:25], mem_rdata_q[11:7]} <= {4'b0, mem_rdata_latched[8:7], mem_rdata_latched[12:9], 2'b00}; 538 | mem_rdata_q[14:12] <= 3'b 010; 539 | end 540 | endcase 541 | end 542 | endcase 543 | end 544 | end 545 | 546 | always @(posedge clk) begin 547 | if (resetn && !trap) begin 548 | if (mem_do_prefetch || mem_do_rinst || mem_do_rdata) 549 | `assert(!mem_do_wdata); 550 | 551 | if (mem_do_prefetch || mem_do_rinst) 552 | `assert(!mem_do_rdata); 553 | 554 | if (mem_do_rdata) 555 | `assert(!mem_do_prefetch && !mem_do_rinst); 556 | 557 | if (mem_do_wdata) 558 | `assert(!(mem_do_prefetch || mem_do_rinst || mem_do_rdata)); 559 | 560 | if (mem_state == 2 || mem_state == 3) 561 | `assert(mem_valid || mem_do_prefetch); 562 | end 563 | end 564 | 565 | always @(posedge clk) begin 566 | if (!resetn || trap) begin 567 | if (!resetn) 568 | mem_state <= 0; 569 | if (!resetn || mem_ready) 570 | mem_valid <= 0; 571 | mem_la_secondword <= 0; 572 | prefetched_high_word <= 0; 573 | end else begin 574 | if (mem_la_read || mem_la_write) begin 575 | mem_addr <= mem_la_addr; 576 | mem_wstrb <= mem_la_wstrb & {4{mem_la_write}}; 577 | end 578 | if (mem_la_write) begin 579 | mem_wdata <= mem_la_wdata; 580 | end 581 | case (mem_state) 582 | 0: begin 583 | if (mem_do_prefetch || mem_do_rinst || mem_do_rdata) begin 584 | mem_valid <= !mem_la_use_prefetched_high_word; 585 | mem_instr <= mem_do_prefetch || mem_do_rinst; 586 | mem_wstrb <= 0; 587 | mem_state <= 1; 588 | end 589 | if (mem_do_wdata) begin 590 | mem_valid <= 1; 591 | mem_instr <= 0; 592 | mem_state <= 2; 593 | end 594 | end 595 | 1: begin 596 | `assert(mem_wstrb == 0); 597 | `assert(mem_do_prefetch || mem_do_rinst || mem_do_rdata); 598 | `assert(mem_valid == !mem_la_use_prefetched_high_word); 599 | `assert(mem_instr == (mem_do_prefetch || mem_do_rinst)); 600 | if (mem_xfer) begin 601 | if (COMPRESSED_ISA && mem_la_read) begin 602 | mem_valid <= 1; 603 | mem_la_secondword <= 1; 604 | if (!mem_la_use_prefetched_high_word) 605 | mem_16bit_buffer <= mem_rdata[31:16]; 606 | end else begin 607 | mem_valid <= 0; 608 | mem_la_secondword <= 0; 609 | if (COMPRESSED_ISA && !mem_do_rdata) begin 610 | if (~&mem_rdata[1:0] || mem_la_secondword) begin 611 | mem_16bit_buffer <= mem_rdata[31:16]; 612 | prefetched_high_word <= 1; 613 | end else begin 614 | prefetched_high_word <= 0; 615 | end 616 | end 617 | mem_state <= mem_do_rinst || mem_do_rdata ? 0 : 3; 618 | end 619 | end 620 | end 621 | 2: begin 622 | `assert(mem_wstrb != 0); 623 | `assert(mem_do_wdata); 624 | if (mem_xfer) begin 625 | mem_valid <= 0; 626 | mem_state <= 0; 627 | end 628 | end 629 | 3: begin 630 | `assert(mem_wstrb == 0); 631 | `assert(mem_do_prefetch); 632 | if (mem_do_rinst) begin 633 | mem_state <= 0; 634 | end 635 | end 636 | endcase 637 | end 638 | 639 | if (clear_prefetched_high_word) 640 | prefetched_high_word <= 0; 641 | end 642 | 643 | 644 | // Instruction Decoder 645 | 646 | reg instr_lui, instr_auipc, instr_jal, instr_jalr; 647 | reg instr_beq, instr_bne, instr_blt, instr_bge, instr_bltu, instr_bgeu; 648 | reg instr_lb, instr_lh, instr_lw, instr_lbu, instr_lhu, instr_sb, instr_sh, instr_sw; 649 | reg instr_addi, instr_slti, instr_sltiu, instr_xori, instr_ori, instr_andi, instr_slli, instr_srli, instr_srai; 650 | reg instr_add, instr_sub, instr_sll, instr_slt, instr_sltu, instr_xor, instr_srl, instr_sra, instr_or, instr_and; 651 | reg instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh, instr_ecall_ebreak, instr_fence; 652 | reg instr_getq, instr_setq, instr_retirq, instr_maskirq, instr_waitirq, instr_timer; 653 | wire instr_trap; 654 | 655 | reg [regindex_bits-1:0] decoded_rd, decoded_rs1; 656 | reg [4:0] decoded_rs2; 657 | reg [31:0] decoded_imm, decoded_imm_j; 658 | reg decoder_trigger; 659 | reg decoder_trigger_q; 660 | reg decoder_pseudo_trigger; 661 | reg decoder_pseudo_trigger_q; 662 | reg compressed_instr; 663 | 664 | reg is_lui_auipc_jal; 665 | reg is_lb_lh_lw_lbu_lhu; 666 | reg is_slli_srli_srai; 667 | reg is_jalr_addi_slti_sltiu_xori_ori_andi; 668 | reg is_sb_sh_sw; 669 | reg is_sll_srl_sra; 670 | reg is_lui_auipc_jal_jalr_addi_add_sub; 671 | reg is_slti_blt_slt; 672 | reg is_sltiu_bltu_sltu; 673 | reg is_beq_bne_blt_bge_bltu_bgeu; 674 | reg is_lbu_lhu_lw; 675 | reg is_alu_reg_imm; 676 | reg is_alu_reg_reg; 677 | reg is_compare; 678 | 679 | assign instr_trap = (CATCH_ILLINSN || WITH_PCPI) && !{instr_lui, instr_auipc, instr_jal, instr_jalr, 680 | instr_beq, instr_bne, instr_blt, instr_bge, instr_bltu, instr_bgeu, 681 | instr_lb, instr_lh, instr_lw, instr_lbu, instr_lhu, instr_sb, instr_sh, instr_sw, 682 | instr_addi, instr_slti, instr_sltiu, instr_xori, instr_ori, instr_andi, instr_slli, instr_srli, instr_srai, 683 | instr_add, instr_sub, instr_sll, instr_slt, instr_sltu, instr_xor, instr_srl, instr_sra, instr_or, instr_and, 684 | instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh, instr_fence, 685 | instr_getq, instr_setq, instr_retirq, instr_maskirq, instr_waitirq, instr_timer}; 686 | 687 | wire is_rdcycle_rdcycleh_rdinstr_rdinstrh; 688 | assign is_rdcycle_rdcycleh_rdinstr_rdinstrh = |{instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh}; 689 | 690 | reg [63:0] new_ascii_instr; 691 | `FORMAL_KEEP reg [63:0] dbg_ascii_instr; 692 | `FORMAL_KEEP reg [31:0] dbg_insn_imm; 693 | `FORMAL_KEEP reg [4:0] dbg_insn_rs1; 694 | `FORMAL_KEEP reg [4:0] dbg_insn_rs2; 695 | `FORMAL_KEEP reg [4:0] dbg_insn_rd; 696 | `FORMAL_KEEP reg [31:0] dbg_rs1val; 697 | `FORMAL_KEEP reg [31:0] dbg_rs2val; 698 | `FORMAL_KEEP reg dbg_rs1val_valid; 699 | `FORMAL_KEEP reg dbg_rs2val_valid; 700 | 701 | always @* begin 702 | new_ascii_instr = ""; 703 | 704 | if (instr_lui) new_ascii_instr = "lui"; 705 | if (instr_auipc) new_ascii_instr = "auipc"; 706 | if (instr_jal) new_ascii_instr = "jal"; 707 | if (instr_jalr) new_ascii_instr = "jalr"; 708 | 709 | if (instr_beq) new_ascii_instr = "beq"; 710 | if (instr_bne) new_ascii_instr = "bne"; 711 | if (instr_blt) new_ascii_instr = "blt"; 712 | if (instr_bge) new_ascii_instr = "bge"; 713 | if (instr_bltu) new_ascii_instr = "bltu"; 714 | if (instr_bgeu) new_ascii_instr = "bgeu"; 715 | 716 | if (instr_lb) new_ascii_instr = "lb"; 717 | if (instr_lh) new_ascii_instr = "lh"; 718 | if (instr_lw) new_ascii_instr = "lw"; 719 | if (instr_lbu) new_ascii_instr = "lbu"; 720 | if (instr_lhu) new_ascii_instr = "lhu"; 721 | if (instr_sb) new_ascii_instr = "sb"; 722 | if (instr_sh) new_ascii_instr = "sh"; 723 | if (instr_sw) new_ascii_instr = "sw"; 724 | 725 | if (instr_addi) new_ascii_instr = "addi"; 726 | if (instr_slti) new_ascii_instr = "slti"; 727 | if (instr_sltiu) new_ascii_instr = "sltiu"; 728 | if (instr_xori) new_ascii_instr = "xori"; 729 | if (instr_ori) new_ascii_instr = "ori"; 730 | if (instr_andi) new_ascii_instr = "andi"; 731 | if (instr_slli) new_ascii_instr = "slli"; 732 | if (instr_srli) new_ascii_instr = "srli"; 733 | if (instr_srai) new_ascii_instr = "srai"; 734 | 735 | if (instr_add) new_ascii_instr = "add"; 736 | if (instr_sub) new_ascii_instr = "sub"; 737 | if (instr_sll) new_ascii_instr = "sll"; 738 | if (instr_slt) new_ascii_instr = "slt"; 739 | if (instr_sltu) new_ascii_instr = "sltu"; 740 | if (instr_xor) new_ascii_instr = "xor"; 741 | if (instr_srl) new_ascii_instr = "srl"; 742 | if (instr_sra) new_ascii_instr = "sra"; 743 | if (instr_or) new_ascii_instr = "or"; 744 | if (instr_and) new_ascii_instr = "and"; 745 | 746 | if (instr_rdcycle) new_ascii_instr = "rdcycle"; 747 | if (instr_rdcycleh) new_ascii_instr = "rdcycleh"; 748 | if (instr_rdinstr) new_ascii_instr = "rdinstr"; 749 | if (instr_rdinstrh) new_ascii_instr = "rdinstrh"; 750 | if (instr_fence) new_ascii_instr = "fence"; 751 | 752 | if (instr_getq) new_ascii_instr = "getq"; 753 | if (instr_setq) new_ascii_instr = "setq"; 754 | if (instr_retirq) new_ascii_instr = "retirq"; 755 | if (instr_maskirq) new_ascii_instr = "maskirq"; 756 | if (instr_waitirq) new_ascii_instr = "waitirq"; 757 | if (instr_timer) new_ascii_instr = "timer"; 758 | end 759 | 760 | reg [63:0] q_ascii_instr; 761 | reg [31:0] q_insn_imm; 762 | reg [31:0] q_insn_opcode; 763 | reg [4:0] q_insn_rs1; 764 | reg [4:0] q_insn_rs2; 765 | reg [4:0] q_insn_rd; 766 | reg dbg_next; 767 | 768 | wire launch_next_insn; 769 | reg dbg_valid_insn; 770 | 771 | reg [63:0] cached_ascii_instr; 772 | reg [31:0] cached_insn_imm; 773 | reg [31:0] cached_insn_opcode; 774 | reg [4:0] cached_insn_rs1; 775 | reg [4:0] cached_insn_rs2; 776 | reg [4:0] cached_insn_rd; 777 | 778 | always @(posedge clk) begin 779 | q_ascii_instr <= dbg_ascii_instr; 780 | q_insn_imm <= dbg_insn_imm; 781 | q_insn_opcode <= dbg_insn_opcode; 782 | q_insn_rs1 <= dbg_insn_rs1; 783 | q_insn_rs2 <= dbg_insn_rs2; 784 | q_insn_rd <= dbg_insn_rd; 785 | dbg_next <= launch_next_insn; 786 | 787 | if (!resetn || trap) 788 | dbg_valid_insn <= 0; 789 | else if (launch_next_insn) 790 | dbg_valid_insn <= 1; 791 | 792 | if (decoder_trigger_q) begin 793 | cached_ascii_instr <= new_ascii_instr; 794 | cached_insn_imm <= decoded_imm; 795 | if (&next_insn_opcode[1:0]) 796 | cached_insn_opcode <= next_insn_opcode; 797 | else 798 | cached_insn_opcode <= {16'b0, next_insn_opcode[15:0]}; 799 | cached_insn_rs1 <= decoded_rs1; 800 | cached_insn_rs2 <= decoded_rs2; 801 | cached_insn_rd <= decoded_rd; 802 | end 803 | 804 | if (launch_next_insn) begin 805 | dbg_insn_addr <= next_pc; 806 | end 807 | end 808 | 809 | always @* begin 810 | dbg_ascii_instr = q_ascii_instr; 811 | dbg_insn_imm = q_insn_imm; 812 | dbg_insn_opcode = q_insn_opcode; 813 | dbg_insn_rs1 = q_insn_rs1; 814 | dbg_insn_rs2 = q_insn_rs2; 815 | dbg_insn_rd = q_insn_rd; 816 | 817 | if (dbg_next) begin 818 | if (decoder_pseudo_trigger_q) begin 819 | dbg_ascii_instr = cached_ascii_instr; 820 | dbg_insn_imm = cached_insn_imm; 821 | dbg_insn_opcode = cached_insn_opcode; 822 | dbg_insn_rs1 = cached_insn_rs1; 823 | dbg_insn_rs2 = cached_insn_rs2; 824 | dbg_insn_rd = cached_insn_rd; 825 | end else begin 826 | dbg_ascii_instr = new_ascii_instr; 827 | if (&next_insn_opcode[1:0]) 828 | dbg_insn_opcode = next_insn_opcode; 829 | else 830 | dbg_insn_opcode = {16'b0, next_insn_opcode[15:0]}; 831 | dbg_insn_imm = decoded_imm; 832 | dbg_insn_rs1 = decoded_rs1; 833 | dbg_insn_rs2 = decoded_rs2; 834 | dbg_insn_rd = decoded_rd; 835 | end 836 | end 837 | end 838 | 839 | `ifdef DEBUGASM 840 | always @(posedge clk) begin 841 | if (dbg_next) begin 842 | $display("debugasm %x %x %s", dbg_insn_addr, dbg_insn_opcode, dbg_ascii_instr ? dbg_ascii_instr : "*"); 843 | end 844 | end 845 | `endif 846 | 847 | `ifdef DEBUG 848 | always @(posedge clk) begin 849 | if (dbg_next) begin 850 | if (&dbg_insn_opcode[1:0]) 851 | $display("DECODE: 0x%08x 0x%08x %-0s", dbg_insn_addr, dbg_insn_opcode, dbg_ascii_instr ? dbg_ascii_instr : "UNKNOWN"); 852 | else 853 | $display("DECODE: 0x%08x 0x%04x %-0s", dbg_insn_addr, dbg_insn_opcode[15:0], dbg_ascii_instr ? dbg_ascii_instr : "UNKNOWN"); 854 | end 855 | end 856 | `endif 857 | 858 | always @(posedge clk) begin 859 | is_lui_auipc_jal <= |{instr_lui, instr_auipc, instr_jal}; 860 | is_lui_auipc_jal_jalr_addi_add_sub <= |{instr_lui, instr_auipc, instr_jal, instr_jalr, instr_addi, instr_add, instr_sub}; 861 | is_slti_blt_slt <= |{instr_slti, instr_blt, instr_slt}; 862 | is_sltiu_bltu_sltu <= |{instr_sltiu, instr_bltu, instr_sltu}; 863 | is_lbu_lhu_lw <= |{instr_lbu, instr_lhu, instr_lw}; 864 | is_compare <= |{is_beq_bne_blt_bge_bltu_bgeu, instr_slti, instr_slt, instr_sltiu, instr_sltu}; 865 | 866 | if (mem_do_rinst && mem_done) begin 867 | instr_lui <= mem_rdata_latched[6:0] == 7'b0110111; 868 | instr_auipc <= mem_rdata_latched[6:0] == 7'b0010111; 869 | instr_jal <= mem_rdata_latched[6:0] == 7'b1101111; 870 | instr_jalr <= mem_rdata_latched[6:0] == 7'b1100111 && mem_rdata_latched[14:12] == 3'b000; 871 | instr_retirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010 && ENABLE_IRQ; 872 | instr_waitirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000100 && ENABLE_IRQ; 873 | 874 | is_beq_bne_blt_bge_bltu_bgeu <= mem_rdata_latched[6:0] == 7'b1100011; 875 | is_lb_lh_lw_lbu_lhu <= mem_rdata_latched[6:0] == 7'b0000011; 876 | is_sb_sh_sw <= mem_rdata_latched[6:0] == 7'b0100011; 877 | is_alu_reg_imm <= mem_rdata_latched[6:0] == 7'b0010011; 878 | is_alu_reg_reg <= mem_rdata_latched[6:0] == 7'b0110011; 879 | 880 | { decoded_imm_j[31:20], decoded_imm_j[10:1], decoded_imm_j[11], decoded_imm_j[19:12], decoded_imm_j[0] } <= $signed({mem_rdata_latched[31:12], 1'b0}); 881 | 882 | decoded_rd <= mem_rdata_latched[11:7]; 883 | decoded_rs1 <= mem_rdata_latched[19:15]; 884 | decoded_rs2 <= mem_rdata_latched[24:20]; 885 | 886 | if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000000 && ENABLE_IRQ && ENABLE_IRQ_QREGS) 887 | decoded_rs1[regindex_bits-1] <= 1; // instr_getq 888 | 889 | if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010 && ENABLE_IRQ) 890 | decoded_rs1 <= ENABLE_IRQ_QREGS ? irqregs_offset : 3; // instr_retirq 891 | 892 | compressed_instr <= 0; 893 | if (COMPRESSED_ISA && mem_rdata_latched[1:0] != 2'b11) begin 894 | compressed_instr <= 1; 895 | decoded_rd <= 0; 896 | decoded_rs1 <= 0; 897 | decoded_rs2 <= 0; 898 | 899 | { decoded_imm_j[31:11], decoded_imm_j[4], decoded_imm_j[9:8], decoded_imm_j[10], decoded_imm_j[6], 900 | decoded_imm_j[7], decoded_imm_j[3:1], decoded_imm_j[5], decoded_imm_j[0] } <= $signed({mem_rdata_latched[12:2], 1'b0}); 901 | 902 | case (mem_rdata_latched[1:0]) 903 | 2'b00: begin // Quadrant 0 904 | case (mem_rdata_latched[15:13]) 905 | 3'b000: begin // C.ADDI4SPN 906 | is_alu_reg_imm <= |mem_rdata_latched[12:5]; 907 | decoded_rs1 <= 2; 908 | decoded_rd <= 8 + mem_rdata_latched[4:2]; 909 | end 910 | 3'b010: begin // C.LW 911 | is_lb_lh_lw_lbu_lhu <= 1; 912 | decoded_rs1 <= 8 + mem_rdata_latched[9:7]; 913 | decoded_rd <= 8 + mem_rdata_latched[4:2]; 914 | end 915 | 3'b110: begin // C.SW 916 | is_sb_sh_sw <= 1; 917 | decoded_rs1 <= 8 + mem_rdata_latched[9:7]; 918 | decoded_rs2 <= 8 + mem_rdata_latched[4:2]; 919 | end 920 | endcase 921 | end 922 | 2'b01: begin // Quadrant 1 923 | case (mem_rdata_latched[15:13]) 924 | 3'b000: begin // C.NOP / C.ADDI 925 | is_alu_reg_imm <= 1; 926 | decoded_rd <= mem_rdata_latched[11:7]; 927 | decoded_rs1 <= mem_rdata_latched[11:7]; 928 | end 929 | 3'b001: begin // C.JAL 930 | instr_jal <= 1; 931 | decoded_rd <= 1; 932 | end 933 | 3'b 010: begin // C.LI 934 | is_alu_reg_imm <= 1; 935 | decoded_rd <= mem_rdata_latched[11:7]; 936 | decoded_rs1 <= 0; 937 | end 938 | 3'b 011: begin 939 | if (mem_rdata_latched[12] || mem_rdata_latched[6:2]) begin 940 | if (mem_rdata_latched[11:7] == 2) begin // C.ADDI16SP 941 | is_alu_reg_imm <= 1; 942 | decoded_rd <= mem_rdata_latched[11:7]; 943 | decoded_rs1 <= mem_rdata_latched[11:7]; 944 | end else begin // C.LUI 945 | instr_lui <= 1; 946 | decoded_rd <= mem_rdata_latched[11:7]; 947 | decoded_rs1 <= 0; 948 | end 949 | end 950 | end 951 | 3'b100: begin 952 | if (!mem_rdata_latched[11] && !mem_rdata_latched[12]) begin // C.SRLI, C.SRAI 953 | is_alu_reg_imm <= 1; 954 | decoded_rd <= 8 + mem_rdata_latched[9:7]; 955 | decoded_rs1 <= 8 + mem_rdata_latched[9:7]; 956 | decoded_rs2 <= {mem_rdata_latched[12], mem_rdata_latched[6:2]}; 957 | end 958 | if (mem_rdata_latched[11:10] == 2'b10) begin // C.ANDI 959 | is_alu_reg_imm <= 1; 960 | decoded_rd <= 8 + mem_rdata_latched[9:7]; 961 | decoded_rs1 <= 8 + mem_rdata_latched[9:7]; 962 | end 963 | if (mem_rdata_latched[12:10] == 3'b011) begin // C.SUB, C.XOR, C.OR, C.AND 964 | is_alu_reg_reg <= 1; 965 | decoded_rd <= 8 + mem_rdata_latched[9:7]; 966 | decoded_rs1 <= 8 + mem_rdata_latched[9:7]; 967 | decoded_rs2 <= 8 + mem_rdata_latched[4:2]; 968 | end 969 | end 970 | 3'b101: begin // C.J 971 | instr_jal <= 1; 972 | end 973 | 3'b110: begin // C.BEQZ 974 | is_beq_bne_blt_bge_bltu_bgeu <= 1; 975 | decoded_rs1 <= 8 + mem_rdata_latched[9:7]; 976 | decoded_rs2 <= 0; 977 | end 978 | 3'b111: begin // C.BNEZ 979 | is_beq_bne_blt_bge_bltu_bgeu <= 1; 980 | decoded_rs1 <= 8 + mem_rdata_latched[9:7]; 981 | decoded_rs2 <= 0; 982 | end 983 | endcase 984 | end 985 | 2'b10: begin // Quadrant 2 986 | case (mem_rdata_latched[15:13]) 987 | 3'b000: begin // C.SLLI 988 | if (!mem_rdata_latched[12]) begin 989 | is_alu_reg_imm <= 1; 990 | decoded_rd <= mem_rdata_latched[11:7]; 991 | decoded_rs1 <= mem_rdata_latched[11:7]; 992 | decoded_rs2 <= {mem_rdata_latched[12], mem_rdata_latched[6:2]}; 993 | end 994 | end 995 | 3'b010: begin // C.LWSP 996 | if (mem_rdata_latched[11:7]) begin 997 | is_lb_lh_lw_lbu_lhu <= 1; 998 | decoded_rd <= mem_rdata_latched[11:7]; 999 | decoded_rs1 <= 2; 1000 | end 1001 | end 1002 | 3'b100: begin 1003 | if (mem_rdata_latched[12] == 0 && mem_rdata_latched[11:7] != 0 && mem_rdata_latched[6:2] == 0) begin // C.JR 1004 | instr_jalr <= 1; 1005 | decoded_rd <= 0; 1006 | decoded_rs1 <= mem_rdata_latched[11:7]; 1007 | end 1008 | if (mem_rdata_latched[12] == 0 && mem_rdata_latched[6:2] != 0) begin // C.MV 1009 | is_alu_reg_reg <= 1; 1010 | decoded_rd <= mem_rdata_latched[11:7]; 1011 | decoded_rs1 <= 0; 1012 | decoded_rs2 <= mem_rdata_latched[6:2]; 1013 | end 1014 | if (mem_rdata_latched[12] != 0 && mem_rdata_latched[11:7] != 0 && mem_rdata_latched[6:2] == 0) begin // C.JALR 1015 | instr_jalr <= 1; 1016 | decoded_rd <= 1; 1017 | decoded_rs1 <= mem_rdata_latched[11:7]; 1018 | end 1019 | if (mem_rdata_latched[12] != 0 && mem_rdata_latched[6:2] != 0) begin // C.ADD 1020 | is_alu_reg_reg <= 1; 1021 | decoded_rd <= mem_rdata_latched[11:7]; 1022 | decoded_rs1 <= mem_rdata_latched[11:7]; 1023 | decoded_rs2 <= mem_rdata_latched[6:2]; 1024 | end 1025 | end 1026 | 3'b110: begin // C.SWSP 1027 | is_sb_sh_sw <= 1; 1028 | decoded_rs1 <= 2; 1029 | decoded_rs2 <= mem_rdata_latched[6:2]; 1030 | end 1031 | endcase 1032 | end 1033 | endcase 1034 | end 1035 | end 1036 | 1037 | if (decoder_trigger && !decoder_pseudo_trigger) begin 1038 | pcpi_insn <= WITH_PCPI ? mem_rdata_q : 'bx; 1039 | 1040 | instr_beq <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b000; 1041 | instr_bne <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b001; 1042 | instr_blt <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b100; 1043 | instr_bge <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b101; 1044 | instr_bltu <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b110; 1045 | instr_bgeu <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b111; 1046 | 1047 | instr_lb <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b000; 1048 | instr_lh <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b001; 1049 | instr_lw <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b010; 1050 | instr_lbu <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b100; 1051 | instr_lhu <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b101; 1052 | 1053 | instr_sb <= is_sb_sh_sw && mem_rdata_q[14:12] == 3'b000; 1054 | instr_sh <= is_sb_sh_sw && mem_rdata_q[14:12] == 3'b001; 1055 | instr_sw <= is_sb_sh_sw && mem_rdata_q[14:12] == 3'b010; 1056 | 1057 | instr_addi <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b000; 1058 | instr_slti <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b010; 1059 | instr_sltiu <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b011; 1060 | instr_xori <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b100; 1061 | instr_ori <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b110; 1062 | instr_andi <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b111; 1063 | 1064 | instr_slli <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000; 1065 | instr_srli <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0000000; 1066 | instr_srai <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0100000; 1067 | 1068 | instr_add <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b000 && mem_rdata_q[31:25] == 7'b0000000; 1069 | instr_sub <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b000 && mem_rdata_q[31:25] == 7'b0100000; 1070 | instr_sll <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000; 1071 | instr_slt <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b010 && mem_rdata_q[31:25] == 7'b0000000; 1072 | instr_sltu <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b011 && mem_rdata_q[31:25] == 7'b0000000; 1073 | instr_xor <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b100 && mem_rdata_q[31:25] == 7'b0000000; 1074 | instr_srl <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0000000; 1075 | instr_sra <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0100000; 1076 | instr_or <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b110 && mem_rdata_q[31:25] == 7'b0000000; 1077 | instr_and <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b111 && mem_rdata_q[31:25] == 7'b0000000; 1078 | 1079 | instr_rdcycle <= ((mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000000000000010) || 1080 | (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000000100000010)) && ENABLE_COUNTERS; 1081 | instr_rdcycleh <= ((mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11001000000000000010) || 1082 | (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11001000000100000010)) && ENABLE_COUNTERS && ENABLE_COUNTERS64; 1083 | instr_rdinstr <= (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000001000000010) && ENABLE_COUNTERS; 1084 | instr_rdinstrh <= (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11001000001000000010) && ENABLE_COUNTERS && ENABLE_COUNTERS64; 1085 | 1086 | instr_ecall_ebreak <= ((mem_rdata_q[6:0] == 7'b1110011 && !mem_rdata_q[31:21] && !mem_rdata_q[19:7]) || 1087 | (COMPRESSED_ISA && mem_rdata_q[15:0] == 16'h9002)); 1088 | instr_fence <= (mem_rdata_q[6:0] == 7'b0001111 && !mem_rdata_q[14:12]); 1089 | 1090 | instr_getq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000000 && ENABLE_IRQ && ENABLE_IRQ_QREGS; 1091 | instr_setq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000001 && ENABLE_IRQ && ENABLE_IRQ_QREGS; 1092 | instr_maskirq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000011 && ENABLE_IRQ; 1093 | instr_timer <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000101 && ENABLE_IRQ && ENABLE_IRQ_TIMER; 1094 | 1095 | is_slli_srli_srai <= is_alu_reg_imm && |{ 1096 | mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000, 1097 | mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0000000, 1098 | mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0100000 1099 | }; 1100 | 1101 | is_jalr_addi_slti_sltiu_xori_ori_andi <= instr_jalr || is_alu_reg_imm && |{ 1102 | mem_rdata_q[14:12] == 3'b000, 1103 | mem_rdata_q[14:12] == 3'b010, 1104 | mem_rdata_q[14:12] == 3'b011, 1105 | mem_rdata_q[14:12] == 3'b100, 1106 | mem_rdata_q[14:12] == 3'b110, 1107 | mem_rdata_q[14:12] == 3'b111 1108 | }; 1109 | 1110 | is_sll_srl_sra <= is_alu_reg_reg && |{ 1111 | mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000, 1112 | mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0000000, 1113 | mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0100000 1114 | }; 1115 | 1116 | is_lui_auipc_jal_jalr_addi_add_sub <= 0; 1117 | is_compare <= 0; 1118 | 1119 | (* parallel_case *) 1120 | case (1'b1) 1121 | instr_jal: 1122 | decoded_imm <= decoded_imm_j; 1123 | |{instr_lui, instr_auipc}: 1124 | decoded_imm <= mem_rdata_q[31:12] << 12; 1125 | |{instr_jalr, is_lb_lh_lw_lbu_lhu, is_alu_reg_imm}: 1126 | decoded_imm <= $signed(mem_rdata_q[31:20]); 1127 | is_beq_bne_blt_bge_bltu_bgeu: 1128 | decoded_imm <= $signed({mem_rdata_q[31], mem_rdata_q[7], mem_rdata_q[30:25], mem_rdata_q[11:8], 1'b0}); 1129 | is_sb_sh_sw: 1130 | decoded_imm <= $signed({mem_rdata_q[31:25], mem_rdata_q[11:7]}); 1131 | default: 1132 | decoded_imm <= 1'bx; 1133 | endcase 1134 | end 1135 | 1136 | if (!resetn) begin 1137 | is_beq_bne_blt_bge_bltu_bgeu <= 0; 1138 | is_compare <= 0; 1139 | 1140 | instr_beq <= 0; 1141 | instr_bne <= 0; 1142 | instr_blt <= 0; 1143 | instr_bge <= 0; 1144 | instr_bltu <= 0; 1145 | instr_bgeu <= 0; 1146 | 1147 | instr_addi <= 0; 1148 | instr_slti <= 0; 1149 | instr_sltiu <= 0; 1150 | instr_xori <= 0; 1151 | instr_ori <= 0; 1152 | instr_andi <= 0; 1153 | 1154 | instr_add <= 0; 1155 | instr_sub <= 0; 1156 | instr_sll <= 0; 1157 | instr_slt <= 0; 1158 | instr_sltu <= 0; 1159 | instr_xor <= 0; 1160 | instr_srl <= 0; 1161 | instr_sra <= 0; 1162 | instr_or <= 0; 1163 | instr_and <= 0; 1164 | 1165 | instr_fence <= 0; 1166 | end 1167 | end 1168 | 1169 | 1170 | // Main State Machine 1171 | 1172 | localparam cpu_state_trap = 8'b10000000; 1173 | localparam cpu_state_fetch = 8'b01000000; 1174 | localparam cpu_state_ld_rs1 = 8'b00100000; 1175 | localparam cpu_state_ld_rs2 = 8'b00010000; 1176 | localparam cpu_state_exec = 8'b00001000; 1177 | localparam cpu_state_shift = 8'b00000100; 1178 | localparam cpu_state_stmem = 8'b00000010; 1179 | localparam cpu_state_ldmem = 8'b00000001; 1180 | 1181 | reg [7:0] cpu_state; 1182 | reg [1:0] irq_state; 1183 | 1184 | `FORMAL_KEEP reg [127:0] dbg_ascii_state; 1185 | 1186 | always @* begin 1187 | dbg_ascii_state = ""; 1188 | if (cpu_state == cpu_state_trap) dbg_ascii_state = "trap"; 1189 | if (cpu_state == cpu_state_fetch) dbg_ascii_state = "fetch"; 1190 | if (cpu_state == cpu_state_ld_rs1) dbg_ascii_state = "ld_rs1"; 1191 | if (cpu_state == cpu_state_ld_rs2) dbg_ascii_state = "ld_rs2"; 1192 | if (cpu_state == cpu_state_exec) dbg_ascii_state = "exec"; 1193 | if (cpu_state == cpu_state_shift) dbg_ascii_state = "shift"; 1194 | if (cpu_state == cpu_state_stmem) dbg_ascii_state = "stmem"; 1195 | if (cpu_state == cpu_state_ldmem) dbg_ascii_state = "ldmem"; 1196 | end 1197 | 1198 | reg set_mem_do_rinst; 1199 | reg set_mem_do_rdata; 1200 | reg set_mem_do_wdata; 1201 | 1202 | reg latched_store; 1203 | reg latched_stalu; 1204 | reg latched_branch; 1205 | reg latched_compr; 1206 | reg latched_trace; 1207 | reg latched_is_lu; 1208 | reg latched_is_lh; 1209 | reg latched_is_lb; 1210 | reg [regindex_bits-1:0] latched_rd; 1211 | 1212 | reg [31:0] current_pc; 1213 | assign next_pc = latched_store && latched_branch ? reg_out & ~1 : reg_next_pc; 1214 | 1215 | reg [3:0] pcpi_timeout_counter; 1216 | reg pcpi_timeout; 1217 | 1218 | reg [31:0] next_irq_pending; 1219 | reg do_waitirq; 1220 | 1221 | reg [31:0] alu_out, alu_out_q; 1222 | reg alu_out_0, alu_out_0_q; 1223 | reg alu_wait, alu_wait_2; 1224 | 1225 | reg [31:0] alu_add_sub; 1226 | reg [31:0] alu_shl, alu_shr; 1227 | reg alu_eq, alu_ltu, alu_lts; 1228 | 1229 | generate if (TWO_CYCLE_ALU) begin 1230 | always @(posedge clk) begin 1231 | alu_add_sub <= instr_sub ? reg_op1 - reg_op2 : reg_op1 + reg_op2; 1232 | alu_eq <= reg_op1 == reg_op2; 1233 | alu_lts <= $signed(reg_op1) < $signed(reg_op2); 1234 | alu_ltu <= reg_op1 < reg_op2; 1235 | alu_shl <= reg_op1 << reg_op2[4:0]; 1236 | alu_shr <= $signed({instr_sra || instr_srai ? reg_op1[31] : 1'b0, reg_op1}) >>> reg_op2[4:0]; 1237 | end 1238 | end else begin 1239 | always @* begin 1240 | alu_add_sub = instr_sub ? reg_op1 - reg_op2 : reg_op1 + reg_op2; 1241 | alu_eq = reg_op1 == reg_op2; 1242 | alu_lts = $signed(reg_op1) < $signed(reg_op2); 1243 | alu_ltu = reg_op1 < reg_op2; 1244 | alu_shl = reg_op1 << reg_op2[4:0]; 1245 | alu_shr = $signed({instr_sra || instr_srai ? reg_op1[31] : 1'b0, reg_op1}) >>> reg_op2[4:0]; 1246 | end 1247 | end endgenerate 1248 | 1249 | always @* begin 1250 | alu_out_0 = 'bx; 1251 | (* parallel_case, full_case *) 1252 | case (1'b1) 1253 | instr_beq: 1254 | alu_out_0 = alu_eq; 1255 | instr_bne: 1256 | alu_out_0 = !alu_eq; 1257 | instr_bge: 1258 | alu_out_0 = !alu_lts; 1259 | instr_bgeu: 1260 | alu_out_0 = !alu_ltu; 1261 | is_slti_blt_slt && (!TWO_CYCLE_COMPARE || !{instr_beq,instr_bne,instr_bge,instr_bgeu}): 1262 | alu_out_0 = alu_lts; 1263 | is_sltiu_bltu_sltu && (!TWO_CYCLE_COMPARE || !{instr_beq,instr_bne,instr_bge,instr_bgeu}): 1264 | alu_out_0 = alu_ltu; 1265 | endcase 1266 | 1267 | alu_out = 'bx; 1268 | (* parallel_case, full_case *) 1269 | case (1'b1) 1270 | is_lui_auipc_jal_jalr_addi_add_sub: 1271 | alu_out = alu_add_sub; 1272 | is_compare: 1273 | alu_out = alu_out_0; 1274 | instr_xori || instr_xor: 1275 | alu_out = reg_op1 ^ reg_op2; 1276 | instr_ori || instr_or: 1277 | alu_out = reg_op1 | reg_op2; 1278 | instr_andi || instr_and: 1279 | alu_out = reg_op1 & reg_op2; 1280 | BARREL_SHIFTER && (instr_sll || instr_slli): 1281 | alu_out = alu_shl; 1282 | BARREL_SHIFTER && (instr_srl || instr_srli || instr_sra || instr_srai): 1283 | alu_out = alu_shr; 1284 | endcase 1285 | 1286 | `ifdef RISCV_FORMAL_BLACKBOX_ALU 1287 | alu_out_0 = $anyseq; 1288 | alu_out = $anyseq; 1289 | `endif 1290 | end 1291 | 1292 | reg clear_prefetched_high_word_q; 1293 | always @(posedge clk) clear_prefetched_high_word_q <= clear_prefetched_high_word; 1294 | 1295 | always @* begin 1296 | clear_prefetched_high_word = clear_prefetched_high_word_q; 1297 | if (!prefetched_high_word) 1298 | clear_prefetched_high_word = 0; 1299 | if (latched_branch || irq_state || !resetn) 1300 | clear_prefetched_high_word = COMPRESSED_ISA; 1301 | end 1302 | 1303 | reg cpuregs_write; 1304 | reg [31:0] cpuregs_wrdata; 1305 | reg [31:0] cpuregs_rs1; 1306 | reg [31:0] cpuregs_rs2; 1307 | reg [regindex_bits-1:0] decoded_rs; 1308 | 1309 | always @* begin 1310 | cpuregs_write = 0; 1311 | cpuregs_wrdata = 'bx; 1312 | 1313 | if (cpu_state == cpu_state_fetch) begin 1314 | (* parallel_case *) 1315 | case (1'b1) 1316 | latched_branch: begin 1317 | cpuregs_wrdata = reg_pc + (latched_compr ? 2 : 4); 1318 | cpuregs_write = 1; 1319 | end 1320 | latched_store && !latched_branch: begin 1321 | cpuregs_wrdata = latched_stalu ? alu_out_q : reg_out; 1322 | cpuregs_write = 1; 1323 | end 1324 | ENABLE_IRQ && irq_state[0]: begin 1325 | cpuregs_wrdata = reg_next_pc | latched_compr; 1326 | cpuregs_write = 1; 1327 | end 1328 | ENABLE_IRQ && irq_state[1]: begin 1329 | cpuregs_wrdata = irq_pending & ~irq_mask; 1330 | cpuregs_write = 1; 1331 | end 1332 | endcase 1333 | end 1334 | end 1335 | 1336 | `ifndef PICORV32_REGS 1337 | always @(posedge clk) begin 1338 | if (resetn && cpuregs_write && latched_rd) 1339 | `ifdef PICORV32_TESTBUG_001 1340 | cpuregs[latched_rd ^ 1] <= cpuregs_wrdata; 1341 | `elsif PICORV32_TESTBUG_002 1342 | cpuregs[latched_rd] <= cpuregs_wrdata ^ 1; 1343 | `else 1344 | cpuregs[latched_rd] <= cpuregs_wrdata; 1345 | `endif 1346 | end 1347 | 1348 | always @* begin 1349 | decoded_rs = 'bx; 1350 | if (ENABLE_REGS_DUALPORT) begin 1351 | `ifndef RISCV_FORMAL_BLACKBOX_REGS 1352 | cpuregs_rs1 = decoded_rs1 ? cpuregs[decoded_rs1] : 0; 1353 | cpuregs_rs2 = decoded_rs2 ? cpuregs[decoded_rs2] : 0; 1354 | `else 1355 | cpuregs_rs1 = decoded_rs1 ? $anyseq : 0; 1356 | cpuregs_rs2 = decoded_rs2 ? $anyseq : 0; 1357 | `endif 1358 | end else begin 1359 | decoded_rs = (cpu_state == cpu_state_ld_rs2) ? decoded_rs2 : decoded_rs1; 1360 | `ifndef RISCV_FORMAL_BLACKBOX_REGS 1361 | cpuregs_rs1 = decoded_rs ? cpuregs[decoded_rs] : 0; 1362 | `else 1363 | cpuregs_rs1 = decoded_rs ? $anyseq : 0; 1364 | `endif 1365 | cpuregs_rs2 = cpuregs_rs1; 1366 | end 1367 | end 1368 | `else 1369 | wire[31:0] cpuregs_rdata1; 1370 | wire[31:0] cpuregs_rdata2; 1371 | 1372 | wire [5:0] cpuregs_waddr = latched_rd; 1373 | wire [5:0] cpuregs_raddr1 = ENABLE_REGS_DUALPORT ? decoded_rs1 : decoded_rs; 1374 | wire [5:0] cpuregs_raddr2 = ENABLE_REGS_DUALPORT ? decoded_rs2 : 0; 1375 | 1376 | `PICORV32_REGS cpuregs ( 1377 | .clk(clk), 1378 | .wen(resetn && cpuregs_write && latched_rd), 1379 | .waddr(cpuregs_waddr), 1380 | .raddr1(cpuregs_raddr1), 1381 | .raddr2(cpuregs_raddr2), 1382 | .wdata(cpuregs_wrdata), 1383 | .rdata1(cpuregs_rdata1), 1384 | .rdata2(cpuregs_rdata2) 1385 | ); 1386 | 1387 | always @* begin 1388 | decoded_rs = 'bx; 1389 | if (ENABLE_REGS_DUALPORT) begin 1390 | cpuregs_rs1 = decoded_rs1 ? cpuregs_rdata1 : 0; 1391 | cpuregs_rs2 = decoded_rs2 ? cpuregs_rdata2 : 0; 1392 | end else begin 1393 | decoded_rs = (cpu_state == cpu_state_ld_rs2) ? decoded_rs2 : decoded_rs1; 1394 | cpuregs_rs1 = decoded_rs ? cpuregs_rdata1 : 0; 1395 | cpuregs_rs2 = cpuregs_rs1; 1396 | end 1397 | end 1398 | `endif 1399 | 1400 | assign launch_next_insn = cpu_state == cpu_state_fetch && decoder_trigger && (!ENABLE_IRQ || irq_delay || irq_active || !(irq_pending & ~irq_mask)); 1401 | 1402 | always @(posedge clk) begin 1403 | trap <= 0; 1404 | reg_sh <= 'bx; 1405 | reg_out <= 'bx; 1406 | set_mem_do_rinst = 0; 1407 | set_mem_do_rdata = 0; 1408 | set_mem_do_wdata = 0; 1409 | 1410 | alu_out_0_q <= alu_out_0; 1411 | alu_out_q <= alu_out; 1412 | 1413 | alu_wait <= 0; 1414 | alu_wait_2 <= 0; 1415 | 1416 | if (launch_next_insn) begin 1417 | dbg_rs1val <= 'bx; 1418 | dbg_rs2val <= 'bx; 1419 | dbg_rs1val_valid <= 0; 1420 | dbg_rs2val_valid <= 0; 1421 | end 1422 | 1423 | if (WITH_PCPI && CATCH_ILLINSN) begin 1424 | if (resetn && pcpi_valid && !pcpi_int_wait) begin 1425 | if (pcpi_timeout_counter) 1426 | pcpi_timeout_counter <= pcpi_timeout_counter - 1; 1427 | end else 1428 | pcpi_timeout_counter <= ~0; 1429 | pcpi_timeout <= !pcpi_timeout_counter; 1430 | end 1431 | 1432 | if (ENABLE_COUNTERS) begin 1433 | count_cycle <= resetn ? count_cycle + 1 : 0; 1434 | if (!ENABLE_COUNTERS64) count_cycle[63:32] <= 0; 1435 | end else begin 1436 | count_cycle <= 'bx; 1437 | count_instr <= 'bx; 1438 | end 1439 | 1440 | next_irq_pending = ENABLE_IRQ ? irq_pending & LATCHED_IRQ : 'bx; 1441 | 1442 | if (ENABLE_IRQ && ENABLE_IRQ_TIMER && timer) begin 1443 | timer <= timer - 1; 1444 | end 1445 | 1446 | decoder_trigger <= mem_do_rinst && mem_done; 1447 | decoder_trigger_q <= decoder_trigger; 1448 | decoder_pseudo_trigger <= 0; 1449 | decoder_pseudo_trigger_q <= decoder_pseudo_trigger; 1450 | do_waitirq <= 0; 1451 | 1452 | trace_valid <= 0; 1453 | 1454 | if (!ENABLE_TRACE) 1455 | trace_data <= 'bx; 1456 | 1457 | if (!resetn) begin 1458 | reg_pc <= PROGADDR_RESET; 1459 | reg_next_pc <= PROGADDR_RESET; 1460 | if (ENABLE_COUNTERS) 1461 | count_instr <= 0; 1462 | latched_store <= 0; 1463 | latched_stalu <= 0; 1464 | latched_branch <= 0; 1465 | latched_trace <= 0; 1466 | latched_is_lu <= 0; 1467 | latched_is_lh <= 0; 1468 | latched_is_lb <= 0; 1469 | pcpi_valid <= 0; 1470 | pcpi_timeout <= 0; 1471 | irq_active <= 0; 1472 | irq_delay <= 0; 1473 | irq_mask <= ~0; 1474 | next_irq_pending = 0; 1475 | irq_state <= 0; 1476 | eoi <= 0; 1477 | timer <= 0; 1478 | if (~STACKADDR) begin 1479 | latched_store <= 1; 1480 | latched_rd <= 2; 1481 | reg_out <= STACKADDR; 1482 | end 1483 | cpu_state <= cpu_state_fetch; 1484 | end else 1485 | (* parallel_case, full_case *) 1486 | case (cpu_state) 1487 | cpu_state_trap: begin 1488 | trap <= 1; 1489 | end 1490 | 1491 | cpu_state_fetch: begin 1492 | mem_do_rinst <= !decoder_trigger && !do_waitirq; 1493 | mem_wordsize <= 0; 1494 | 1495 | current_pc = reg_next_pc; 1496 | 1497 | (* parallel_case *) 1498 | case (1'b1) 1499 | latched_branch: begin 1500 | current_pc = latched_store ? (latched_stalu ? alu_out_q : reg_out) & ~1 : reg_next_pc; 1501 | `debug($display("ST_RD: %2d 0x%08x, BRANCH 0x%08x", latched_rd, reg_pc + (latched_compr ? 2 : 4), current_pc);) 1502 | end 1503 | latched_store && !latched_branch: begin 1504 | `debug($display("ST_RD: %2d 0x%08x", latched_rd, latched_stalu ? alu_out_q : reg_out);) 1505 | end 1506 | ENABLE_IRQ && irq_state[0]: begin 1507 | current_pc = PROGADDR_IRQ; 1508 | irq_active <= 1; 1509 | mem_do_rinst <= 1; 1510 | end 1511 | ENABLE_IRQ && irq_state[1]: begin 1512 | eoi <= irq_pending & ~irq_mask; 1513 | next_irq_pending = next_irq_pending & irq_mask; 1514 | end 1515 | endcase 1516 | 1517 | if (ENABLE_TRACE && latched_trace) begin 1518 | latched_trace <= 0; 1519 | trace_valid <= 1; 1520 | if (latched_branch) 1521 | trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_BRANCH | (current_pc & 32'hfffffffe); 1522 | else 1523 | trace_data <= (irq_active ? TRACE_IRQ : 0) | (latched_stalu ? alu_out_q : reg_out); 1524 | end 1525 | 1526 | reg_pc <= current_pc; 1527 | reg_next_pc <= current_pc; 1528 | 1529 | latched_store <= 0; 1530 | latched_stalu <= 0; 1531 | latched_branch <= 0; 1532 | latched_is_lu <= 0; 1533 | latched_is_lh <= 0; 1534 | latched_is_lb <= 0; 1535 | latched_rd <= decoded_rd; 1536 | latched_compr <= compressed_instr; 1537 | 1538 | if (ENABLE_IRQ && ((decoder_trigger && !irq_active && !irq_delay && |(irq_pending & ~irq_mask)) || irq_state)) begin 1539 | irq_state <= 1540 | irq_state == 2'b00 ? 2'b01 : 1541 | irq_state == 2'b01 ? 2'b10 : 2'b00; 1542 | latched_compr <= latched_compr; 1543 | if (ENABLE_IRQ_QREGS) 1544 | latched_rd <= irqregs_offset | irq_state[0]; 1545 | else 1546 | latched_rd <= irq_state[0] ? 4 : 3; 1547 | end else 1548 | if (ENABLE_IRQ && (decoder_trigger || do_waitirq) && instr_waitirq) begin 1549 | if (irq_pending) begin 1550 | latched_store <= 1; 1551 | reg_out <= irq_pending; 1552 | reg_next_pc <= current_pc + (compressed_instr ? 2 : 4); 1553 | mem_do_rinst <= 1; 1554 | end else 1555 | do_waitirq <= 1; 1556 | end else 1557 | if (decoder_trigger) begin 1558 | `debug($display("-- %-0t", $time);) 1559 | irq_delay <= irq_active; 1560 | reg_next_pc <= current_pc + (compressed_instr ? 2 : 4); 1561 | if (ENABLE_TRACE) 1562 | latched_trace <= 1; 1563 | if (ENABLE_COUNTERS) begin 1564 | count_instr <= count_instr + 1; 1565 | if (!ENABLE_COUNTERS64) count_instr[63:32] <= 0; 1566 | end 1567 | if (instr_jal) begin 1568 | mem_do_rinst <= 1; 1569 | reg_next_pc <= current_pc + decoded_imm_j; 1570 | latched_branch <= 1; 1571 | end else begin 1572 | mem_do_rinst <= 0; 1573 | mem_do_prefetch <= !instr_jalr && !instr_retirq; 1574 | cpu_state <= cpu_state_ld_rs1; 1575 | end 1576 | end 1577 | end 1578 | 1579 | cpu_state_ld_rs1: begin 1580 | reg_op1 <= 'bx; 1581 | reg_op2 <= 'bx; 1582 | 1583 | (* parallel_case *) 1584 | case (1'b1) 1585 | (CATCH_ILLINSN || WITH_PCPI) && instr_trap: begin 1586 | if (WITH_PCPI) begin 1587 | `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) 1588 | reg_op1 <= cpuregs_rs1; 1589 | dbg_rs1val <= cpuregs_rs1; 1590 | dbg_rs1val_valid <= 1; 1591 | if (ENABLE_REGS_DUALPORT) begin 1592 | pcpi_valid <= 1; 1593 | `debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, cpuregs_rs2);) 1594 | reg_sh <= cpuregs_rs2; 1595 | reg_op2 <= cpuregs_rs2; 1596 | dbg_rs2val <= cpuregs_rs2; 1597 | dbg_rs2val_valid <= 1; 1598 | if (pcpi_int_ready) begin 1599 | mem_do_rinst <= 1; 1600 | pcpi_valid <= 0; 1601 | reg_out <= pcpi_int_rd; 1602 | latched_store <= pcpi_int_wr; 1603 | cpu_state <= cpu_state_fetch; 1604 | end else 1605 | if (CATCH_ILLINSN && (pcpi_timeout || instr_ecall_ebreak)) begin 1606 | pcpi_valid <= 0; 1607 | `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);) 1608 | if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin 1609 | next_irq_pending[irq_ebreak] = 1; 1610 | cpu_state <= cpu_state_fetch; 1611 | end else 1612 | cpu_state <= cpu_state_trap; 1613 | end 1614 | end else begin 1615 | cpu_state <= cpu_state_ld_rs2; 1616 | end 1617 | end else begin 1618 | `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);) 1619 | if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin 1620 | next_irq_pending[irq_ebreak] = 1; 1621 | cpu_state <= cpu_state_fetch; 1622 | end else 1623 | cpu_state <= cpu_state_trap; 1624 | end 1625 | end 1626 | ENABLE_COUNTERS && is_rdcycle_rdcycleh_rdinstr_rdinstrh: begin 1627 | (* parallel_case, full_case *) 1628 | case (1'b1) 1629 | instr_rdcycle: 1630 | reg_out <= count_cycle[31:0]; 1631 | instr_rdcycleh && ENABLE_COUNTERS64: 1632 | reg_out <= count_cycle[63:32]; 1633 | instr_rdinstr: 1634 | reg_out <= count_instr[31:0]; 1635 | instr_rdinstrh && ENABLE_COUNTERS64: 1636 | reg_out <= count_instr[63:32]; 1637 | endcase 1638 | latched_store <= 1; 1639 | cpu_state <= cpu_state_fetch; 1640 | end 1641 | is_lui_auipc_jal: begin 1642 | reg_op1 <= instr_lui ? 0 : reg_pc; 1643 | reg_op2 <= decoded_imm; 1644 | if (TWO_CYCLE_ALU) 1645 | alu_wait <= 1; 1646 | else 1647 | mem_do_rinst <= mem_do_prefetch; 1648 | cpu_state <= cpu_state_exec; 1649 | end 1650 | ENABLE_IRQ && ENABLE_IRQ_QREGS && instr_getq: begin 1651 | `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) 1652 | reg_out <= cpuregs_rs1; 1653 | dbg_rs1val <= cpuregs_rs1; 1654 | dbg_rs1val_valid <= 1; 1655 | latched_store <= 1; 1656 | cpu_state <= cpu_state_fetch; 1657 | end 1658 | ENABLE_IRQ && ENABLE_IRQ_QREGS && instr_setq: begin 1659 | `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) 1660 | reg_out <= cpuregs_rs1; 1661 | dbg_rs1val <= cpuregs_rs1; 1662 | dbg_rs1val_valid <= 1; 1663 | latched_rd <= latched_rd | irqregs_offset; 1664 | latched_store <= 1; 1665 | cpu_state <= cpu_state_fetch; 1666 | end 1667 | ENABLE_IRQ && instr_retirq: begin 1668 | eoi <= 0; 1669 | irq_active <= 0; 1670 | latched_branch <= 1; 1671 | latched_store <= 1; 1672 | `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) 1673 | reg_out <= CATCH_MISALIGN ? (cpuregs_rs1 & 32'h fffffffe) : cpuregs_rs1; 1674 | dbg_rs1val <= cpuregs_rs1; 1675 | dbg_rs1val_valid <= 1; 1676 | cpu_state <= cpu_state_fetch; 1677 | end 1678 | ENABLE_IRQ && instr_maskirq: begin 1679 | latched_store <= 1; 1680 | reg_out <= irq_mask; 1681 | `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) 1682 | irq_mask <= cpuregs_rs1 | MASKED_IRQ; 1683 | dbg_rs1val <= cpuregs_rs1; 1684 | dbg_rs1val_valid <= 1; 1685 | cpu_state <= cpu_state_fetch; 1686 | end 1687 | ENABLE_IRQ && ENABLE_IRQ_TIMER && instr_timer: begin 1688 | latched_store <= 1; 1689 | reg_out <= timer; 1690 | `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) 1691 | timer <= cpuregs_rs1; 1692 | dbg_rs1val <= cpuregs_rs1; 1693 | dbg_rs1val_valid <= 1; 1694 | cpu_state <= cpu_state_fetch; 1695 | end 1696 | is_lb_lh_lw_lbu_lhu && !instr_trap: begin 1697 | `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) 1698 | reg_op1 <= cpuregs_rs1; 1699 | dbg_rs1val <= cpuregs_rs1; 1700 | dbg_rs1val_valid <= 1; 1701 | cpu_state <= cpu_state_ldmem; 1702 | mem_do_rinst <= 1; 1703 | end 1704 | is_slli_srli_srai && !BARREL_SHIFTER: begin 1705 | `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) 1706 | reg_op1 <= cpuregs_rs1; 1707 | dbg_rs1val <= cpuregs_rs1; 1708 | dbg_rs1val_valid <= 1; 1709 | reg_sh <= decoded_rs2; 1710 | cpu_state <= cpu_state_shift; 1711 | end 1712 | is_jalr_addi_slti_sltiu_xori_ori_andi, is_slli_srli_srai && BARREL_SHIFTER: begin 1713 | `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) 1714 | reg_op1 <= cpuregs_rs1; 1715 | dbg_rs1val <= cpuregs_rs1; 1716 | dbg_rs1val_valid <= 1; 1717 | reg_op2 <= is_slli_srli_srai && BARREL_SHIFTER ? decoded_rs2 : decoded_imm; 1718 | if (TWO_CYCLE_ALU) 1719 | alu_wait <= 1; 1720 | else 1721 | mem_do_rinst <= mem_do_prefetch; 1722 | cpu_state <= cpu_state_exec; 1723 | end 1724 | default: begin 1725 | `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) 1726 | reg_op1 <= cpuregs_rs1; 1727 | dbg_rs1val <= cpuregs_rs1; 1728 | dbg_rs1val_valid <= 1; 1729 | if (ENABLE_REGS_DUALPORT) begin 1730 | `debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, cpuregs_rs2);) 1731 | reg_sh <= cpuregs_rs2; 1732 | reg_op2 <= cpuregs_rs2; 1733 | dbg_rs2val <= cpuregs_rs2; 1734 | dbg_rs2val_valid <= 1; 1735 | (* parallel_case *) 1736 | case (1'b1) 1737 | is_sb_sh_sw: begin 1738 | cpu_state <= cpu_state_stmem; 1739 | mem_do_rinst <= 1; 1740 | end 1741 | is_sll_srl_sra && !BARREL_SHIFTER: begin 1742 | cpu_state <= cpu_state_shift; 1743 | end 1744 | default: begin 1745 | if (TWO_CYCLE_ALU || (TWO_CYCLE_COMPARE && is_beq_bne_blt_bge_bltu_bgeu)) begin 1746 | alu_wait_2 <= TWO_CYCLE_ALU && (TWO_CYCLE_COMPARE && is_beq_bne_blt_bge_bltu_bgeu); 1747 | alu_wait <= 1; 1748 | end else 1749 | mem_do_rinst <= mem_do_prefetch; 1750 | cpu_state <= cpu_state_exec; 1751 | end 1752 | endcase 1753 | end else 1754 | cpu_state <= cpu_state_ld_rs2; 1755 | end 1756 | endcase 1757 | end 1758 | 1759 | cpu_state_ld_rs2: begin 1760 | `debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, cpuregs_rs2);) 1761 | reg_sh <= cpuregs_rs2; 1762 | reg_op2 <= cpuregs_rs2; 1763 | dbg_rs2val <= cpuregs_rs2; 1764 | dbg_rs2val_valid <= 1; 1765 | 1766 | (* parallel_case *) 1767 | case (1'b1) 1768 | WITH_PCPI && instr_trap: begin 1769 | pcpi_valid <= 1; 1770 | if (pcpi_int_ready) begin 1771 | mem_do_rinst <= 1; 1772 | pcpi_valid <= 0; 1773 | reg_out <= pcpi_int_rd; 1774 | latched_store <= pcpi_int_wr; 1775 | cpu_state <= cpu_state_fetch; 1776 | end else 1777 | if (CATCH_ILLINSN && (pcpi_timeout || instr_ecall_ebreak)) begin 1778 | pcpi_valid <= 0; 1779 | `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);) 1780 | if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin 1781 | next_irq_pending[irq_ebreak] = 1; 1782 | cpu_state <= cpu_state_fetch; 1783 | end else 1784 | cpu_state <= cpu_state_trap; 1785 | end 1786 | end 1787 | is_sb_sh_sw: begin 1788 | cpu_state <= cpu_state_stmem; 1789 | mem_do_rinst <= 1; 1790 | end 1791 | is_sll_srl_sra && !BARREL_SHIFTER: begin 1792 | cpu_state <= cpu_state_shift; 1793 | end 1794 | default: begin 1795 | if (TWO_CYCLE_ALU || (TWO_CYCLE_COMPARE && is_beq_bne_blt_bge_bltu_bgeu)) begin 1796 | alu_wait_2 <= TWO_CYCLE_ALU && (TWO_CYCLE_COMPARE && is_beq_bne_blt_bge_bltu_bgeu); 1797 | alu_wait <= 1; 1798 | end else 1799 | mem_do_rinst <= mem_do_prefetch; 1800 | cpu_state <= cpu_state_exec; 1801 | end 1802 | endcase 1803 | end 1804 | 1805 | cpu_state_exec: begin 1806 | reg_out <= reg_pc + decoded_imm; 1807 | if ((TWO_CYCLE_ALU || TWO_CYCLE_COMPARE) && (alu_wait || alu_wait_2)) begin 1808 | mem_do_rinst <= mem_do_prefetch && !alu_wait_2; 1809 | alu_wait <= alu_wait_2; 1810 | end else 1811 | if (is_beq_bne_blt_bge_bltu_bgeu) begin 1812 | latched_rd <= 0; 1813 | latched_store <= TWO_CYCLE_COMPARE ? alu_out_0_q : alu_out_0; 1814 | latched_branch <= TWO_CYCLE_COMPARE ? alu_out_0_q : alu_out_0; 1815 | if (mem_done) 1816 | cpu_state <= cpu_state_fetch; 1817 | if (TWO_CYCLE_COMPARE ? alu_out_0_q : alu_out_0) begin 1818 | decoder_trigger <= 0; 1819 | set_mem_do_rinst = 1; 1820 | end 1821 | end else begin 1822 | latched_branch <= instr_jalr; 1823 | latched_store <= 1; 1824 | latched_stalu <= 1; 1825 | cpu_state <= cpu_state_fetch; 1826 | end 1827 | end 1828 | 1829 | cpu_state_shift: begin 1830 | latched_store <= 1; 1831 | if (reg_sh == 0) begin 1832 | reg_out <= reg_op1; 1833 | mem_do_rinst <= mem_do_prefetch; 1834 | cpu_state <= cpu_state_fetch; 1835 | end else if (TWO_STAGE_SHIFT && reg_sh >= 4) begin 1836 | (* parallel_case, full_case *) 1837 | case (1'b1) 1838 | instr_slli || instr_sll: reg_op1 <= reg_op1 << 4; 1839 | instr_srli || instr_srl: reg_op1 <= reg_op1 >> 4; 1840 | instr_srai || instr_sra: reg_op1 <= $signed(reg_op1) >>> 4; 1841 | endcase 1842 | reg_sh <= reg_sh - 4; 1843 | end else begin 1844 | (* parallel_case, full_case *) 1845 | case (1'b1) 1846 | instr_slli || instr_sll: reg_op1 <= reg_op1 << 1; 1847 | instr_srli || instr_srl: reg_op1 <= reg_op1 >> 1; 1848 | instr_srai || instr_sra: reg_op1 <= $signed(reg_op1) >>> 1; 1849 | endcase 1850 | reg_sh <= reg_sh - 1; 1851 | end 1852 | end 1853 | 1854 | cpu_state_stmem: begin 1855 | if (ENABLE_TRACE) 1856 | reg_out <= reg_op2; 1857 | if (!mem_do_prefetch || mem_done) begin 1858 | if (!mem_do_wdata) begin 1859 | (* parallel_case, full_case *) 1860 | case (1'b1) 1861 | instr_sb: mem_wordsize <= 2; 1862 | instr_sh: mem_wordsize <= 1; 1863 | instr_sw: mem_wordsize <= 0; 1864 | endcase 1865 | if (ENABLE_TRACE) begin 1866 | trace_valid <= 1; 1867 | trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_ADDR | ((reg_op1 + decoded_imm) & 32'hffffffff); 1868 | end 1869 | reg_op1 <= reg_op1 + decoded_imm; 1870 | set_mem_do_wdata = 1; 1871 | end 1872 | if (!mem_do_prefetch && mem_done) begin 1873 | cpu_state <= cpu_state_fetch; 1874 | decoder_trigger <= 1; 1875 | decoder_pseudo_trigger <= 1; 1876 | end 1877 | end 1878 | end 1879 | 1880 | cpu_state_ldmem: begin 1881 | latched_store <= 1; 1882 | if (!mem_do_prefetch || mem_done) begin 1883 | if (!mem_do_rdata) begin 1884 | (* parallel_case, full_case *) 1885 | case (1'b1) 1886 | instr_lb || instr_lbu: mem_wordsize <= 2; 1887 | instr_lh || instr_lhu: mem_wordsize <= 1; 1888 | instr_lw: mem_wordsize <= 0; 1889 | endcase 1890 | latched_is_lu <= is_lbu_lhu_lw; 1891 | latched_is_lh <= instr_lh; 1892 | latched_is_lb <= instr_lb; 1893 | if (ENABLE_TRACE) begin 1894 | trace_valid <= 1; 1895 | trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_ADDR | ((reg_op1 + decoded_imm) & 32'hffffffff); 1896 | end 1897 | reg_op1 <= reg_op1 + decoded_imm; 1898 | set_mem_do_rdata = 1; 1899 | end 1900 | if (!mem_do_prefetch && mem_done) begin 1901 | (* parallel_case, full_case *) 1902 | case (1'b1) 1903 | latched_is_lu: reg_out <= mem_rdata_word; 1904 | latched_is_lh: reg_out <= $signed(mem_rdata_word[15:0]); 1905 | latched_is_lb: reg_out <= $signed(mem_rdata_word[7:0]); 1906 | endcase 1907 | decoder_trigger <= 1; 1908 | decoder_pseudo_trigger <= 1; 1909 | cpu_state <= cpu_state_fetch; 1910 | end 1911 | end 1912 | end 1913 | endcase 1914 | 1915 | if (ENABLE_IRQ) begin 1916 | next_irq_pending = next_irq_pending | irq; 1917 | if(ENABLE_IRQ_TIMER && timer) 1918 | if (timer - 1 == 0) 1919 | next_irq_pending[irq_timer] = 1; 1920 | end 1921 | 1922 | if (CATCH_MISALIGN && resetn && (mem_do_rdata || mem_do_wdata)) begin 1923 | if (mem_wordsize == 0 && reg_op1[1:0] != 0) begin 1924 | `debug($display("MISALIGNED WORD: 0x%08x", reg_op1);) 1925 | if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin 1926 | next_irq_pending[irq_buserror] = 1; 1927 | end else 1928 | cpu_state <= cpu_state_trap; 1929 | end 1930 | if (mem_wordsize == 1 && reg_op1[0] != 0) begin 1931 | `debug($display("MISALIGNED HALFWORD: 0x%08x", reg_op1);) 1932 | if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin 1933 | next_irq_pending[irq_buserror] = 1; 1934 | end else 1935 | cpu_state <= cpu_state_trap; 1936 | end 1937 | end 1938 | if (CATCH_MISALIGN && resetn && mem_do_rinst && (COMPRESSED_ISA ? reg_pc[0] : |reg_pc[1:0])) begin 1939 | `debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);) 1940 | if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin 1941 | next_irq_pending[irq_buserror] = 1; 1942 | end else 1943 | cpu_state <= cpu_state_trap; 1944 | end 1945 | if (!CATCH_ILLINSN && decoder_trigger_q && !decoder_pseudo_trigger_q && instr_ecall_ebreak) begin 1946 | cpu_state <= cpu_state_trap; 1947 | end 1948 | 1949 | if (!resetn || mem_done) begin 1950 | mem_do_prefetch <= 0; 1951 | mem_do_rinst <= 0; 1952 | mem_do_rdata <= 0; 1953 | mem_do_wdata <= 0; 1954 | end 1955 | 1956 | if (set_mem_do_rinst) 1957 | mem_do_rinst <= 1; 1958 | if (set_mem_do_rdata) 1959 | mem_do_rdata <= 1; 1960 | if (set_mem_do_wdata) 1961 | mem_do_wdata <= 1; 1962 | 1963 | irq_pending <= next_irq_pending & ~MASKED_IRQ; 1964 | 1965 | if (!CATCH_MISALIGN) begin 1966 | if (COMPRESSED_ISA) begin 1967 | reg_pc[0] <= 0; 1968 | reg_next_pc[0] <= 0; 1969 | end else begin 1970 | reg_pc[1:0] <= 0; 1971 | reg_next_pc[1:0] <= 0; 1972 | end 1973 | end 1974 | current_pc = 'bx; 1975 | end 1976 | 1977 | `ifdef RISCV_FORMAL 1978 | reg dbg_irq_call; 1979 | reg dbg_irq_enter; 1980 | reg [31:0] dbg_irq_ret; 1981 | always @(posedge clk) begin 1982 | rvfi_valid <= resetn && (launch_next_insn || trap) && dbg_valid_insn; 1983 | rvfi_order <= resetn ? rvfi_order + rvfi_valid : 0; 1984 | 1985 | rvfi_insn <= dbg_insn_opcode; 1986 | rvfi_rs1_addr <= dbg_rs1val_valid ? dbg_insn_rs1 : 0; 1987 | rvfi_rs2_addr <= dbg_rs2val_valid ? dbg_insn_rs2 : 0; 1988 | rvfi_pc_rdata <= dbg_insn_addr; 1989 | rvfi_rs1_rdata <= dbg_rs1val_valid ? dbg_rs1val : 0; 1990 | rvfi_rs2_rdata <= dbg_rs2val_valid ? dbg_rs2val : 0; 1991 | rvfi_trap <= trap; 1992 | rvfi_halt <= trap; 1993 | rvfi_intr <= dbg_irq_enter; 1994 | rvfi_mode <= 3; 1995 | rvfi_ixl <= 1; 1996 | 1997 | if (!resetn) begin 1998 | dbg_irq_call <= 0; 1999 | dbg_irq_enter <= 0; 2000 | end else 2001 | if (rvfi_valid) begin 2002 | dbg_irq_call <= 0; 2003 | dbg_irq_enter <= dbg_irq_call; 2004 | end else 2005 | if (irq_state == 1) begin 2006 | dbg_irq_call <= 1; 2007 | dbg_irq_ret <= next_pc; 2008 | end 2009 | 2010 | if (!resetn) begin 2011 | rvfi_rd_addr <= 0; 2012 | rvfi_rd_wdata <= 0; 2013 | end else 2014 | if (cpuregs_write && !irq_state) begin 2015 | `ifdef PICORV32_TESTBUG_003 2016 | rvfi_rd_addr <= latched_rd ^ 1; 2017 | `else 2018 | rvfi_rd_addr <= latched_rd; 2019 | `endif 2020 | `ifdef PICORV32_TESTBUG_004 2021 | rvfi_rd_wdata <= latched_rd ? cpuregs_wrdata ^ 1 : 0; 2022 | `else 2023 | rvfi_rd_wdata <= latched_rd ? cpuregs_wrdata : 0; 2024 | `endif 2025 | end else 2026 | if (rvfi_valid) begin 2027 | rvfi_rd_addr <= 0; 2028 | rvfi_rd_wdata <= 0; 2029 | end 2030 | 2031 | casez (dbg_insn_opcode) 2032 | 32'b 0000000_?????_000??_???_?????_0001011: begin // getq 2033 | rvfi_rs1_addr <= 0; 2034 | rvfi_rs1_rdata <= 0; 2035 | end 2036 | 32'b 0000001_?????_?????_???_000??_0001011: begin // setq 2037 | rvfi_rd_addr <= 0; 2038 | rvfi_rd_wdata <= 0; 2039 | end 2040 | 32'b 0000010_?????_00000_???_00000_0001011: begin // retirq 2041 | rvfi_rs1_addr <= 0; 2042 | rvfi_rs1_rdata <= 0; 2043 | end 2044 | endcase 2045 | 2046 | if (!dbg_irq_call) begin 2047 | if (dbg_mem_instr) begin 2048 | rvfi_mem_addr <= 0; 2049 | rvfi_mem_rmask <= 0; 2050 | rvfi_mem_wmask <= 0; 2051 | rvfi_mem_rdata <= 0; 2052 | rvfi_mem_wdata <= 0; 2053 | end else 2054 | if (dbg_mem_valid && dbg_mem_ready) begin 2055 | rvfi_mem_addr <= dbg_mem_addr; 2056 | rvfi_mem_rmask <= dbg_mem_wstrb ? 0 : ~0; 2057 | rvfi_mem_wmask <= dbg_mem_wstrb; 2058 | rvfi_mem_rdata <= dbg_mem_rdata; 2059 | rvfi_mem_wdata <= dbg_mem_wdata; 2060 | end 2061 | end 2062 | end 2063 | 2064 | always @* begin 2065 | `ifdef PICORV32_TESTBUG_005 2066 | rvfi_pc_wdata = (dbg_irq_call ? dbg_irq_ret : dbg_insn_addr) ^ 4; 2067 | `else 2068 | rvfi_pc_wdata = dbg_irq_call ? dbg_irq_ret : dbg_insn_addr; 2069 | `endif 2070 | 2071 | rvfi_csr_mcycle_rmask = 0; 2072 | rvfi_csr_mcycle_wmask = 0; 2073 | rvfi_csr_mcycle_rdata = 0; 2074 | rvfi_csr_mcycle_wdata = 0; 2075 | 2076 | rvfi_csr_minstret_rmask = 0; 2077 | rvfi_csr_minstret_wmask = 0; 2078 | rvfi_csr_minstret_rdata = 0; 2079 | rvfi_csr_minstret_wdata = 0; 2080 | 2081 | if (rvfi_valid && rvfi_insn[6:0] == 7'b 1110011 && rvfi_insn[13:12] == 3'b010) begin 2082 | if (rvfi_insn[31:20] == 12'h C00) begin 2083 | rvfi_csr_mcycle_rmask = 64'h 0000_0000_FFFF_FFFF; 2084 | rvfi_csr_mcycle_rdata = {32'h 0000_0000, rvfi_rd_wdata}; 2085 | end 2086 | if (rvfi_insn[31:20] == 12'h C80) begin 2087 | rvfi_csr_mcycle_rmask = 64'h FFFF_FFFF_0000_0000; 2088 | rvfi_csr_mcycle_rdata = {rvfi_rd_wdata, 32'h 0000_0000}; 2089 | end 2090 | if (rvfi_insn[31:20] == 12'h C02) begin 2091 | rvfi_csr_minstret_rmask = 64'h 0000_0000_FFFF_FFFF; 2092 | rvfi_csr_minstret_rdata = {32'h 0000_0000, rvfi_rd_wdata}; 2093 | end 2094 | if (rvfi_insn[31:20] == 12'h C82) begin 2095 | rvfi_csr_minstret_rmask = 64'h FFFF_FFFF_0000_0000; 2096 | rvfi_csr_minstret_rdata = {rvfi_rd_wdata, 32'h 0000_0000}; 2097 | end 2098 | end 2099 | end 2100 | `endif 2101 | 2102 | // Formal Verification 2103 | `ifdef FORMAL 2104 | reg [3:0] last_mem_nowait; 2105 | always @(posedge clk) 2106 | last_mem_nowait <= {last_mem_nowait, mem_ready || !mem_valid}; 2107 | 2108 | // stall the memory interface for max 4 cycles 2109 | restrict property (|last_mem_nowait || mem_ready || !mem_valid); 2110 | 2111 | // resetn low in first cycle, after that resetn high 2112 | restrict property (resetn != $initstate); 2113 | 2114 | // this just makes it much easier to read traces. uncomment as needed. 2115 | // assume property (mem_valid || !mem_ready); 2116 | 2117 | reg ok; 2118 | always @* begin 2119 | if (resetn) begin 2120 | // instruction fetches are read-only 2121 | if (mem_valid && mem_instr) 2122 | assert (mem_wstrb == 0); 2123 | 2124 | // cpu_state must be valid 2125 | ok = 0; 2126 | if (cpu_state == cpu_state_trap) ok = 1; 2127 | if (cpu_state == cpu_state_fetch) ok = 1; 2128 | if (cpu_state == cpu_state_ld_rs1) ok = 1; 2129 | if (cpu_state == cpu_state_ld_rs2) ok = !ENABLE_REGS_DUALPORT; 2130 | if (cpu_state == cpu_state_exec) ok = 1; 2131 | if (cpu_state == cpu_state_shift) ok = 1; 2132 | if (cpu_state == cpu_state_stmem) ok = 1; 2133 | if (cpu_state == cpu_state_ldmem) ok = 1; 2134 | assert (ok); 2135 | end 2136 | end 2137 | 2138 | reg last_mem_la_read = 0; 2139 | reg last_mem_la_write = 0; 2140 | reg [31:0] last_mem_la_addr; 2141 | reg [31:0] last_mem_la_wdata; 2142 | reg [3:0] last_mem_la_wstrb = 0; 2143 | 2144 | always @(posedge clk) begin 2145 | last_mem_la_read <= mem_la_read; 2146 | last_mem_la_write <= mem_la_write; 2147 | last_mem_la_addr <= mem_la_addr; 2148 | last_mem_la_wdata <= mem_la_wdata; 2149 | last_mem_la_wstrb <= mem_la_wstrb; 2150 | 2151 | if (last_mem_la_read) begin 2152 | assert(mem_valid); 2153 | assert(mem_addr == last_mem_la_addr); 2154 | assert(mem_wstrb == 0); 2155 | end 2156 | if (last_mem_la_write) begin 2157 | assert(mem_valid); 2158 | assert(mem_addr == last_mem_la_addr); 2159 | assert(mem_wdata == last_mem_la_wdata); 2160 | assert(mem_wstrb == last_mem_la_wstrb); 2161 | end 2162 | if (mem_la_read || mem_la_write) begin 2163 | assert(!mem_valid || mem_ready); 2164 | end 2165 | end 2166 | `endif 2167 | endmodule 2168 | 2169 | // This is a simple example implementation of PICORV32_REGS. 2170 | // Use the PICORV32_REGS mechanism if you want to use custom 2171 | // memory resources to implement the processor register file. 2172 | // Note that your implementation must match the requirements of 2173 | // the PicoRV32 configuration. (e.g. QREGS, etc) 2174 | module picorv32_regs ( 2175 | input clk, wen, 2176 | input [5:0] waddr, 2177 | input [5:0] raddr1, 2178 | input [5:0] raddr2, 2179 | input [31:0] wdata, 2180 | output [31:0] rdata1, 2181 | output [31:0] rdata2 2182 | ); 2183 | reg [31:0] regs [0:30]; 2184 | 2185 | always @(posedge clk) 2186 | if (wen) regs[~waddr[4:0]] <= wdata; 2187 | 2188 | assign rdata1 = regs[~raddr1[4:0]]; 2189 | assign rdata2 = regs[~raddr2[4:0]]; 2190 | endmodule 2191 | 2192 | 2193 | /*************************************************************** 2194 | * picorv32_pcpi_mul 2195 | ***************************************************************/ 2196 | 2197 | module picorv32_pcpi_mul #( 2198 | parameter STEPS_AT_ONCE = 1, 2199 | parameter CARRY_CHAIN = 4 2200 | ) ( 2201 | input clk, resetn, 2202 | 2203 | input pcpi_valid, 2204 | input [31:0] pcpi_insn, 2205 | input [31:0] pcpi_rs1, 2206 | input [31:0] pcpi_rs2, 2207 | output reg pcpi_wr, 2208 | output reg [31:0] pcpi_rd, 2209 | output reg pcpi_wait, 2210 | output reg pcpi_ready 2211 | ); 2212 | reg instr_mul, instr_mulh, instr_mulhsu, instr_mulhu; 2213 | wire instr_any_mul = |{instr_mul, instr_mulh, instr_mulhsu, instr_mulhu}; 2214 | wire instr_any_mulh = |{instr_mulh, instr_mulhsu, instr_mulhu}; 2215 | wire instr_rs1_signed = |{instr_mulh, instr_mulhsu}; 2216 | wire instr_rs2_signed = |{instr_mulh}; 2217 | 2218 | reg pcpi_wait_q; 2219 | wire mul_start = pcpi_wait && !pcpi_wait_q; 2220 | 2221 | always @(posedge clk) begin 2222 | instr_mul <= 0; 2223 | instr_mulh <= 0; 2224 | instr_mulhsu <= 0; 2225 | instr_mulhu <= 0; 2226 | 2227 | if (resetn && pcpi_valid && pcpi_insn[6:0] == 7'b0110011 && pcpi_insn[31:25] == 7'b0000001) begin 2228 | case (pcpi_insn[14:12]) 2229 | 3'b000: instr_mul <= 1; 2230 | 3'b001: instr_mulh <= 1; 2231 | 3'b010: instr_mulhsu <= 1; 2232 | 3'b011: instr_mulhu <= 1; 2233 | endcase 2234 | end 2235 | 2236 | pcpi_wait <= instr_any_mul; 2237 | pcpi_wait_q <= pcpi_wait; 2238 | end 2239 | 2240 | reg [63:0] rs1, rs2, rd, rdx; 2241 | reg [63:0] next_rs1, next_rs2, this_rs2; 2242 | reg [63:0] next_rd, next_rdx, next_rdt; 2243 | reg [6:0] mul_counter; 2244 | reg mul_waiting; 2245 | reg mul_finish; 2246 | integer i, j; 2247 | 2248 | // carry save accumulator 2249 | always @* begin 2250 | next_rd = rd; 2251 | next_rdx = rdx; 2252 | next_rs1 = rs1; 2253 | next_rs2 = rs2; 2254 | 2255 | for (i = 0; i < STEPS_AT_ONCE; i=i+1) begin 2256 | this_rs2 = next_rs1[0] ? next_rs2 : 0; 2257 | if (CARRY_CHAIN == 0) begin 2258 | next_rdt = next_rd ^ next_rdx ^ this_rs2; 2259 | next_rdx = ((next_rd & next_rdx) | (next_rd & this_rs2) | (next_rdx & this_rs2)) << 1; 2260 | next_rd = next_rdt; 2261 | end else begin 2262 | next_rdt = 0; 2263 | for (j = 0; j < 64; j = j + CARRY_CHAIN) 2264 | {next_rdt[j+CARRY_CHAIN-1], next_rd[j +: CARRY_CHAIN]} = 2265 | next_rd[j +: CARRY_CHAIN] + next_rdx[j +: CARRY_CHAIN] + this_rs2[j +: CARRY_CHAIN]; 2266 | next_rdx = next_rdt << 1; 2267 | end 2268 | next_rs1 = next_rs1 >> 1; 2269 | next_rs2 = next_rs2 << 1; 2270 | end 2271 | end 2272 | 2273 | always @(posedge clk) begin 2274 | mul_finish <= 0; 2275 | if (!resetn) begin 2276 | mul_waiting <= 1; 2277 | end else 2278 | if (mul_waiting) begin 2279 | if (instr_rs1_signed) 2280 | rs1 <= $signed(pcpi_rs1); 2281 | else 2282 | rs1 <= $unsigned(pcpi_rs1); 2283 | 2284 | if (instr_rs2_signed) 2285 | rs2 <= $signed(pcpi_rs2); 2286 | else 2287 | rs2 <= $unsigned(pcpi_rs2); 2288 | 2289 | rd <= 0; 2290 | rdx <= 0; 2291 | mul_counter <= (instr_any_mulh ? 63 - STEPS_AT_ONCE : 31 - STEPS_AT_ONCE); 2292 | mul_waiting <= !mul_start; 2293 | end else begin 2294 | rd <= next_rd; 2295 | rdx <= next_rdx; 2296 | rs1 <= next_rs1; 2297 | rs2 <= next_rs2; 2298 | 2299 | mul_counter <= mul_counter - STEPS_AT_ONCE; 2300 | if (mul_counter[6]) begin 2301 | mul_finish <= 1; 2302 | mul_waiting <= 1; 2303 | end 2304 | end 2305 | end 2306 | 2307 | always @(posedge clk) begin 2308 | pcpi_wr <= 0; 2309 | pcpi_ready <= 0; 2310 | if (mul_finish && resetn) begin 2311 | pcpi_wr <= 1; 2312 | pcpi_ready <= 1; 2313 | pcpi_rd <= instr_any_mulh ? rd >> 32 : rd; 2314 | end 2315 | end 2316 | endmodule 2317 | 2318 | module picorv32_pcpi_fast_mul #( 2319 | parameter EXTRA_MUL_FFS = 0, 2320 | parameter EXTRA_INSN_FFS = 0, 2321 | parameter MUL_CLKGATE = 0 2322 | ) ( 2323 | input clk, resetn, 2324 | 2325 | input pcpi_valid, 2326 | input [31:0] pcpi_insn, 2327 | input [31:0] pcpi_rs1, 2328 | input [31:0] pcpi_rs2, 2329 | output pcpi_wr, 2330 | output [31:0] pcpi_rd, 2331 | output pcpi_wait, 2332 | output pcpi_ready 2333 | ); 2334 | reg instr_mul, instr_mulh, instr_mulhsu, instr_mulhu; 2335 | wire instr_any_mul = |{instr_mul, instr_mulh, instr_mulhsu, instr_mulhu}; 2336 | wire instr_any_mulh = |{instr_mulh, instr_mulhsu, instr_mulhu}; 2337 | wire instr_rs1_signed = |{instr_mulh, instr_mulhsu}; 2338 | wire instr_rs2_signed = |{instr_mulh}; 2339 | 2340 | reg shift_out; 2341 | reg [3:0] active; 2342 | reg [32:0] rs1, rs2, rs1_q, rs2_q; 2343 | reg [63:0] rd, rd_q; 2344 | 2345 | wire pcpi_insn_valid = pcpi_valid && pcpi_insn[6:0] == 7'b0110011 && pcpi_insn[31:25] == 7'b0000001; 2346 | reg pcpi_insn_valid_q; 2347 | 2348 | always @* begin 2349 | instr_mul = 0; 2350 | instr_mulh = 0; 2351 | instr_mulhsu = 0; 2352 | instr_mulhu = 0; 2353 | 2354 | if (resetn && (EXTRA_INSN_FFS ? pcpi_insn_valid_q : pcpi_insn_valid)) begin 2355 | case (pcpi_insn[14:12]) 2356 | 3'b000: instr_mul = 1; 2357 | 3'b001: instr_mulh = 1; 2358 | 3'b010: instr_mulhsu = 1; 2359 | 3'b011: instr_mulhu = 1; 2360 | endcase 2361 | end 2362 | end 2363 | 2364 | always @(posedge clk) begin 2365 | pcpi_insn_valid_q <= pcpi_insn_valid; 2366 | if (!MUL_CLKGATE || active[0]) begin 2367 | rs1_q <= rs1; 2368 | rs2_q <= rs2; 2369 | end 2370 | if (!MUL_CLKGATE || active[1]) begin 2371 | rd <= $signed(EXTRA_MUL_FFS ? rs1_q : rs1) * $signed(EXTRA_MUL_FFS ? rs2_q : rs2); 2372 | end 2373 | if (!MUL_CLKGATE || active[2]) begin 2374 | rd_q <= rd; 2375 | end 2376 | end 2377 | 2378 | always @(posedge clk) begin 2379 | if (instr_any_mul && !(EXTRA_MUL_FFS ? active[3:0] : active[1:0])) begin 2380 | if (instr_rs1_signed) 2381 | rs1 <= $signed(pcpi_rs1); 2382 | else 2383 | rs1 <= $unsigned(pcpi_rs1); 2384 | 2385 | if (instr_rs2_signed) 2386 | rs2 <= $signed(pcpi_rs2); 2387 | else 2388 | rs2 <= $unsigned(pcpi_rs2); 2389 | active[0] <= 1; 2390 | end else begin 2391 | active[0] <= 0; 2392 | end 2393 | 2394 | active[3:1] <= active; 2395 | shift_out <= instr_any_mulh; 2396 | 2397 | if (!resetn) 2398 | active <= 0; 2399 | end 2400 | 2401 | assign pcpi_wr = active[EXTRA_MUL_FFS ? 3 : 1]; 2402 | assign pcpi_wait = 0; 2403 | assign pcpi_ready = active[EXTRA_MUL_FFS ? 3 : 1]; 2404 | `ifdef RISCV_FORMAL_ALTOPS 2405 | assign pcpi_rd = 2406 | instr_mul ? (pcpi_rs1 + pcpi_rs2) ^ 32'h5876063e : 2407 | instr_mulh ? (pcpi_rs1 + pcpi_rs2) ^ 32'hf6583fb7 : 2408 | instr_mulhsu ? (pcpi_rs1 - pcpi_rs2) ^ 32'hecfbe137 : 2409 | instr_mulhu ? (pcpi_rs1 + pcpi_rs2) ^ 32'h949ce5e8 : 1'bx; 2410 | `else 2411 | assign pcpi_rd = shift_out ? (EXTRA_MUL_FFS ? rd_q : rd) >> 32 : (EXTRA_MUL_FFS ? rd_q : rd); 2412 | `endif 2413 | endmodule 2414 | 2415 | 2416 | /*************************************************************** 2417 | * picorv32_pcpi_div 2418 | ***************************************************************/ 2419 | 2420 | module picorv32_pcpi_div ( 2421 | input clk, resetn, 2422 | 2423 | input pcpi_valid, 2424 | input [31:0] pcpi_insn, 2425 | input [31:0] pcpi_rs1, 2426 | input [31:0] pcpi_rs2, 2427 | output reg pcpi_wr, 2428 | output reg [31:0] pcpi_rd, 2429 | output reg pcpi_wait, 2430 | output reg pcpi_ready 2431 | ); 2432 | reg instr_div, instr_divu, instr_rem, instr_remu; 2433 | wire instr_any_div_rem = |{instr_div, instr_divu, instr_rem, instr_remu}; 2434 | 2435 | reg pcpi_wait_q; 2436 | wire start = pcpi_wait && !pcpi_wait_q; 2437 | 2438 | always @(posedge clk) begin 2439 | instr_div <= 0; 2440 | instr_divu <= 0; 2441 | instr_rem <= 0; 2442 | instr_remu <= 0; 2443 | 2444 | if (resetn && pcpi_valid && !pcpi_ready && pcpi_insn[6:0] == 7'b0110011 && pcpi_insn[31:25] == 7'b0000001) begin 2445 | case (pcpi_insn[14:12]) 2446 | 3'b100: instr_div <= 1; 2447 | 3'b101: instr_divu <= 1; 2448 | 3'b110: instr_rem <= 1; 2449 | 3'b111: instr_remu <= 1; 2450 | endcase 2451 | end 2452 | 2453 | pcpi_wait <= instr_any_div_rem && resetn; 2454 | pcpi_wait_q <= pcpi_wait && resetn; 2455 | end 2456 | 2457 | reg [31:0] dividend; 2458 | reg [62:0] divisor; 2459 | reg [31:0] quotient; 2460 | reg [31:0] quotient_msk; 2461 | reg running; 2462 | reg outsign; 2463 | 2464 | always @(posedge clk) begin 2465 | pcpi_ready <= 0; 2466 | pcpi_wr <= 0; 2467 | pcpi_rd <= 'bx; 2468 | 2469 | if (!resetn) begin 2470 | running <= 0; 2471 | end else 2472 | if (start) begin 2473 | running <= 1; 2474 | dividend <= (instr_div || instr_rem) && pcpi_rs1[31] ? -pcpi_rs1 : pcpi_rs1; 2475 | divisor <= ((instr_div || instr_rem) && pcpi_rs2[31] ? -pcpi_rs2 : pcpi_rs2) << 31; 2476 | outsign <= (instr_div && (pcpi_rs1[31] != pcpi_rs2[31]) && |pcpi_rs2) || (instr_rem && pcpi_rs1[31]); 2477 | quotient <= 0; 2478 | quotient_msk <= 1 << 31; 2479 | end else 2480 | if (!quotient_msk && running) begin 2481 | running <= 0; 2482 | pcpi_ready <= 1; 2483 | pcpi_wr <= 1; 2484 | `ifdef RISCV_FORMAL_ALTOPS 2485 | case (1) 2486 | instr_div: pcpi_rd <= (pcpi_rs1 - pcpi_rs2) ^ 32'h7f8529ec; 2487 | instr_divu: pcpi_rd <= (pcpi_rs1 - pcpi_rs2) ^ 32'h10e8fd70; 2488 | instr_rem: pcpi_rd <= (pcpi_rs1 - pcpi_rs2) ^ 32'h8da68fa5; 2489 | instr_remu: pcpi_rd <= (pcpi_rs1 - pcpi_rs2) ^ 32'h3138d0e1; 2490 | endcase 2491 | `else 2492 | if (instr_div || instr_divu) 2493 | pcpi_rd <= outsign ? -quotient : quotient; 2494 | else 2495 | pcpi_rd <= outsign ? -dividend : dividend; 2496 | `endif 2497 | end else begin 2498 | if (divisor <= dividend) begin 2499 | dividend <= dividend - divisor; 2500 | quotient <= quotient | quotient_msk; 2501 | end 2502 | divisor <= divisor >> 1; 2503 | `ifdef RISCV_FORMAL_ALTOPS 2504 | quotient_msk <= quotient_msk >> 5; 2505 | `else 2506 | quotient_msk <= quotient_msk >> 1; 2507 | `endif 2508 | end 2509 | end 2510 | endmodule 2511 | 2512 | 2513 | /*************************************************************** 2514 | * picorv32_axi 2515 | ***************************************************************/ 2516 | 2517 | module picorv32_axi #( 2518 | parameter [ 0:0] ENABLE_COUNTERS = 1, 2519 | parameter [ 0:0] ENABLE_COUNTERS64 = 1, 2520 | parameter [ 0:0] ENABLE_REGS_16_31 = 1, 2521 | parameter [ 0:0] ENABLE_REGS_DUALPORT = 1, 2522 | parameter [ 0:0] TWO_STAGE_SHIFT = 1, 2523 | parameter [ 0:0] BARREL_SHIFTER = 0, 2524 | parameter [ 0:0] TWO_CYCLE_COMPARE = 0, 2525 | parameter [ 0:0] TWO_CYCLE_ALU = 0, 2526 | parameter [ 0:0] COMPRESSED_ISA = 0, 2527 | parameter [ 0:0] CATCH_MISALIGN = 1, 2528 | parameter [ 0:0] CATCH_ILLINSN = 1, 2529 | parameter [ 0:0] ENABLE_PCPI = 0, 2530 | parameter [ 0:0] ENABLE_MUL = 0, 2531 | parameter [ 0:0] ENABLE_FAST_MUL = 0, 2532 | parameter [ 0:0] ENABLE_DIV = 0, 2533 | parameter [ 0:0] ENABLE_IRQ = 0, 2534 | parameter [ 0:0] ENABLE_IRQ_QREGS = 1, 2535 | parameter [ 0:0] ENABLE_IRQ_TIMER = 1, 2536 | parameter [ 0:0] ENABLE_TRACE = 0, 2537 | parameter [ 0:0] REGS_INIT_ZERO = 0, 2538 | parameter [31:0] MASKED_IRQ = 32'h 0000_0000, 2539 | parameter [31:0] LATCHED_IRQ = 32'h ffff_ffff, 2540 | parameter [31:0] PROGADDR_RESET = 32'h 0000_0000, 2541 | parameter [31:0] PROGADDR_IRQ = 32'h 0000_0010, 2542 | parameter [31:0] STACKADDR = 32'h ffff_ffff 2543 | ) ( 2544 | input clk, resetn, 2545 | output trap, 2546 | 2547 | // AXI4-lite master memory interface 2548 | 2549 | output mem_axi_awvalid, 2550 | input mem_axi_awready, 2551 | output [31:0] mem_axi_awaddr, 2552 | output [ 2:0] mem_axi_awprot, 2553 | 2554 | output mem_axi_wvalid, 2555 | input mem_axi_wready, 2556 | output [31:0] mem_axi_wdata, 2557 | output [ 3:0] mem_axi_wstrb, 2558 | 2559 | input mem_axi_bvalid, 2560 | output mem_axi_bready, 2561 | 2562 | output mem_axi_arvalid, 2563 | input mem_axi_arready, 2564 | output [31:0] mem_axi_araddr, 2565 | output [ 2:0] mem_axi_arprot, 2566 | 2567 | input mem_axi_rvalid, 2568 | output mem_axi_rready, 2569 | input [31:0] mem_axi_rdata, 2570 | 2571 | // Pico Co-Processor Interface (PCPI) 2572 | output pcpi_valid, 2573 | output [31:0] pcpi_insn, 2574 | output [31:0] pcpi_rs1, 2575 | output [31:0] pcpi_rs2, 2576 | input pcpi_wr, 2577 | input [31:0] pcpi_rd, 2578 | input pcpi_wait, 2579 | input pcpi_ready, 2580 | 2581 | // IRQ interface 2582 | input [31:0] irq, 2583 | output [31:0] eoi, 2584 | 2585 | `ifdef RISCV_FORMAL 2586 | output rvfi_valid, 2587 | output [63:0] rvfi_order, 2588 | output [31:0] rvfi_insn, 2589 | output rvfi_trap, 2590 | output rvfi_halt, 2591 | output rvfi_intr, 2592 | output [ 4:0] rvfi_rs1_addr, 2593 | output [ 4:0] rvfi_rs2_addr, 2594 | output [31:0] rvfi_rs1_rdata, 2595 | output [31:0] rvfi_rs2_rdata, 2596 | output [ 4:0] rvfi_rd_addr, 2597 | output [31:0] rvfi_rd_wdata, 2598 | output [31:0] rvfi_pc_rdata, 2599 | output [31:0] rvfi_pc_wdata, 2600 | output [31:0] rvfi_mem_addr, 2601 | output [ 3:0] rvfi_mem_rmask, 2602 | output [ 3:0] rvfi_mem_wmask, 2603 | output [31:0] rvfi_mem_rdata, 2604 | output [31:0] rvfi_mem_wdata, 2605 | `endif 2606 | 2607 | // Trace Interface 2608 | output trace_valid, 2609 | output [35:0] trace_data 2610 | ); 2611 | wire mem_valid; 2612 | wire [31:0] mem_addr; 2613 | wire [31:0] mem_wdata; 2614 | wire [ 3:0] mem_wstrb; 2615 | wire mem_instr; 2616 | wire mem_ready; 2617 | wire [31:0] mem_rdata; 2618 | 2619 | picorv32_axi_adapter axi_adapter ( 2620 | .clk (clk ), 2621 | .resetn (resetn ), 2622 | .mem_axi_awvalid(mem_axi_awvalid), 2623 | .mem_axi_awready(mem_axi_awready), 2624 | .mem_axi_awaddr (mem_axi_awaddr ), 2625 | .mem_axi_awprot (mem_axi_awprot ), 2626 | .mem_axi_wvalid (mem_axi_wvalid ), 2627 | .mem_axi_wready (mem_axi_wready ), 2628 | .mem_axi_wdata (mem_axi_wdata ), 2629 | .mem_axi_wstrb (mem_axi_wstrb ), 2630 | .mem_axi_bvalid (mem_axi_bvalid ), 2631 | .mem_axi_bready (mem_axi_bready ), 2632 | .mem_axi_arvalid(mem_axi_arvalid), 2633 | .mem_axi_arready(mem_axi_arready), 2634 | .mem_axi_araddr (mem_axi_araddr ), 2635 | .mem_axi_arprot (mem_axi_arprot ), 2636 | .mem_axi_rvalid (mem_axi_rvalid ), 2637 | .mem_axi_rready (mem_axi_rready ), 2638 | .mem_axi_rdata (mem_axi_rdata ), 2639 | .mem_valid (mem_valid ), 2640 | .mem_instr (mem_instr ), 2641 | .mem_ready (mem_ready ), 2642 | .mem_addr (mem_addr ), 2643 | .mem_wdata (mem_wdata ), 2644 | .mem_wstrb (mem_wstrb ), 2645 | .mem_rdata (mem_rdata ) 2646 | ); 2647 | 2648 | picorv32 #( 2649 | .ENABLE_COUNTERS (ENABLE_COUNTERS ), 2650 | .ENABLE_COUNTERS64 (ENABLE_COUNTERS64 ), 2651 | .ENABLE_REGS_16_31 (ENABLE_REGS_16_31 ), 2652 | .ENABLE_REGS_DUALPORT(ENABLE_REGS_DUALPORT), 2653 | .TWO_STAGE_SHIFT (TWO_STAGE_SHIFT ), 2654 | .BARREL_SHIFTER (BARREL_SHIFTER ), 2655 | .TWO_CYCLE_COMPARE (TWO_CYCLE_COMPARE ), 2656 | .TWO_CYCLE_ALU (TWO_CYCLE_ALU ), 2657 | .COMPRESSED_ISA (COMPRESSED_ISA ), 2658 | .CATCH_MISALIGN (CATCH_MISALIGN ), 2659 | .CATCH_ILLINSN (CATCH_ILLINSN ), 2660 | .ENABLE_PCPI (ENABLE_PCPI ), 2661 | .ENABLE_MUL (ENABLE_MUL ), 2662 | .ENABLE_FAST_MUL (ENABLE_FAST_MUL ), 2663 | .ENABLE_DIV (ENABLE_DIV ), 2664 | .ENABLE_IRQ (ENABLE_IRQ ), 2665 | .ENABLE_IRQ_QREGS (ENABLE_IRQ_QREGS ), 2666 | .ENABLE_IRQ_TIMER (ENABLE_IRQ_TIMER ), 2667 | .ENABLE_TRACE (ENABLE_TRACE ), 2668 | .REGS_INIT_ZERO (REGS_INIT_ZERO ), 2669 | .MASKED_IRQ (MASKED_IRQ ), 2670 | .LATCHED_IRQ (LATCHED_IRQ ), 2671 | .PROGADDR_RESET (PROGADDR_RESET ), 2672 | .PROGADDR_IRQ (PROGADDR_IRQ ), 2673 | .STACKADDR (STACKADDR ) 2674 | ) picorv32_core ( 2675 | .clk (clk ), 2676 | .resetn (resetn), 2677 | .trap (trap ), 2678 | 2679 | .mem_valid(mem_valid), 2680 | .mem_addr (mem_addr ), 2681 | .mem_wdata(mem_wdata), 2682 | .mem_wstrb(mem_wstrb), 2683 | .mem_instr(mem_instr), 2684 | .mem_ready(mem_ready), 2685 | .mem_rdata(mem_rdata), 2686 | 2687 | .pcpi_valid(pcpi_valid), 2688 | .pcpi_insn (pcpi_insn ), 2689 | .pcpi_rs1 (pcpi_rs1 ), 2690 | .pcpi_rs2 (pcpi_rs2 ), 2691 | .pcpi_wr (pcpi_wr ), 2692 | .pcpi_rd (pcpi_rd ), 2693 | .pcpi_wait (pcpi_wait ), 2694 | .pcpi_ready(pcpi_ready), 2695 | 2696 | .irq(irq), 2697 | .eoi(eoi), 2698 | 2699 | `ifdef RISCV_FORMAL 2700 | .rvfi_valid (rvfi_valid ), 2701 | .rvfi_order (rvfi_order ), 2702 | .rvfi_insn (rvfi_insn ), 2703 | .rvfi_trap (rvfi_trap ), 2704 | .rvfi_halt (rvfi_halt ), 2705 | .rvfi_intr (rvfi_intr ), 2706 | .rvfi_rs1_addr (rvfi_rs1_addr ), 2707 | .rvfi_rs2_addr (rvfi_rs2_addr ), 2708 | .rvfi_rs1_rdata(rvfi_rs1_rdata), 2709 | .rvfi_rs2_rdata(rvfi_rs2_rdata), 2710 | .rvfi_rd_addr (rvfi_rd_addr ), 2711 | .rvfi_rd_wdata (rvfi_rd_wdata ), 2712 | .rvfi_pc_rdata (rvfi_pc_rdata ), 2713 | .rvfi_pc_wdata (rvfi_pc_wdata ), 2714 | .rvfi_mem_addr (rvfi_mem_addr ), 2715 | .rvfi_mem_rmask(rvfi_mem_rmask), 2716 | .rvfi_mem_wmask(rvfi_mem_wmask), 2717 | .rvfi_mem_rdata(rvfi_mem_rdata), 2718 | .rvfi_mem_wdata(rvfi_mem_wdata), 2719 | `endif 2720 | 2721 | .trace_valid(trace_valid), 2722 | .trace_data (trace_data) 2723 | ); 2724 | endmodule 2725 | 2726 | 2727 | /*************************************************************** 2728 | * picorv32_axi_adapter 2729 | ***************************************************************/ 2730 | 2731 | module picorv32_axi_adapter ( 2732 | input clk, resetn, 2733 | 2734 | // AXI4-lite master memory interface 2735 | 2736 | output mem_axi_awvalid, 2737 | input mem_axi_awready, 2738 | output [31:0] mem_axi_awaddr, 2739 | output [ 2:0] mem_axi_awprot, 2740 | 2741 | output mem_axi_wvalid, 2742 | input mem_axi_wready, 2743 | output [31:0] mem_axi_wdata, 2744 | output [ 3:0] mem_axi_wstrb, 2745 | 2746 | input mem_axi_bvalid, 2747 | output mem_axi_bready, 2748 | 2749 | output mem_axi_arvalid, 2750 | input mem_axi_arready, 2751 | output [31:0] mem_axi_araddr, 2752 | output [ 2:0] mem_axi_arprot, 2753 | 2754 | input mem_axi_rvalid, 2755 | output mem_axi_rready, 2756 | input [31:0] mem_axi_rdata, 2757 | 2758 | // Native PicoRV32 memory interface 2759 | 2760 | input mem_valid, 2761 | input mem_instr, 2762 | output mem_ready, 2763 | input [31:0] mem_addr, 2764 | input [31:0] mem_wdata, 2765 | input [ 3:0] mem_wstrb, 2766 | output [31:0] mem_rdata 2767 | ); 2768 | reg ack_awvalid; 2769 | reg ack_arvalid; 2770 | reg ack_wvalid; 2771 | reg xfer_done; 2772 | 2773 | assign mem_axi_awvalid = mem_valid && |mem_wstrb && !ack_awvalid; 2774 | assign mem_axi_awaddr = mem_addr; 2775 | assign mem_axi_awprot = 0; 2776 | 2777 | assign mem_axi_arvalid = mem_valid && !mem_wstrb && !ack_arvalid; 2778 | assign mem_axi_araddr = mem_addr; 2779 | assign mem_axi_arprot = mem_instr ? 3'b100 : 3'b000; 2780 | 2781 | assign mem_axi_wvalid = mem_valid && |mem_wstrb && !ack_wvalid; 2782 | assign mem_axi_wdata = mem_wdata; 2783 | assign mem_axi_wstrb = mem_wstrb; 2784 | 2785 | assign mem_ready = mem_axi_bvalid || mem_axi_rvalid; 2786 | assign mem_axi_bready = mem_valid && |mem_wstrb; 2787 | assign mem_axi_rready = mem_valid && !mem_wstrb; 2788 | assign mem_rdata = mem_axi_rdata; 2789 | 2790 | always @(posedge clk) begin 2791 | if (!resetn) begin 2792 | ack_awvalid <= 0; 2793 | end else begin 2794 | xfer_done <= mem_valid && mem_ready; 2795 | if (mem_axi_awready && mem_axi_awvalid) 2796 | ack_awvalid <= 1; 2797 | if (mem_axi_arready && mem_axi_arvalid) 2798 | ack_arvalid <= 1; 2799 | if (mem_axi_wready && mem_axi_wvalid) 2800 | ack_wvalid <= 1; 2801 | if (xfer_done || !mem_valid) begin 2802 | ack_awvalid <= 0; 2803 | ack_arvalid <= 0; 2804 | ack_wvalid <= 0; 2805 | end 2806 | end 2807 | end 2808 | endmodule 2809 | 2810 | 2811 | /*************************************************************** 2812 | * picorv32_wb 2813 | ***************************************************************/ 2814 | 2815 | module picorv32_wb #( 2816 | parameter [ 0:0] ENABLE_COUNTERS = 1, 2817 | parameter [ 0:0] ENABLE_COUNTERS64 = 1, 2818 | parameter [ 0:0] ENABLE_REGS_16_31 = 1, 2819 | parameter [ 0:0] ENABLE_REGS_DUALPORT = 1, 2820 | parameter [ 0:0] TWO_STAGE_SHIFT = 1, 2821 | parameter [ 0:0] BARREL_SHIFTER = 0, 2822 | parameter [ 0:0] TWO_CYCLE_COMPARE = 0, 2823 | parameter [ 0:0] TWO_CYCLE_ALU = 0, 2824 | parameter [ 0:0] COMPRESSED_ISA = 0, 2825 | parameter [ 0:0] CATCH_MISALIGN = 1, 2826 | parameter [ 0:0] CATCH_ILLINSN = 1, 2827 | parameter [ 0:0] ENABLE_PCPI = 0, 2828 | parameter [ 0:0] ENABLE_MUL = 0, 2829 | parameter [ 0:0] ENABLE_FAST_MUL = 0, 2830 | parameter [ 0:0] ENABLE_DIV = 0, 2831 | parameter [ 0:0] ENABLE_IRQ = 0, 2832 | parameter [ 0:0] ENABLE_IRQ_QREGS = 1, 2833 | parameter [ 0:0] ENABLE_IRQ_TIMER = 1, 2834 | parameter [ 0:0] ENABLE_TRACE = 0, 2835 | parameter [ 0:0] REGS_INIT_ZERO = 0, 2836 | parameter [31:0] MASKED_IRQ = 32'h 0000_0000, 2837 | parameter [31:0] LATCHED_IRQ = 32'h ffff_ffff, 2838 | parameter [31:0] PROGADDR_RESET = 32'h 0000_0000, 2839 | parameter [31:0] PROGADDR_IRQ = 32'h 0000_0010, 2840 | parameter [31:0] STACKADDR = 32'h ffff_ffff 2841 | ) ( 2842 | output trap, 2843 | 2844 | // Wishbone interfaces 2845 | input wb_rst_i, 2846 | input wb_clk_i, 2847 | 2848 | output reg [31:0] wbm_adr_o, 2849 | output reg [31:0] wbm_dat_o, 2850 | input [31:0] wbm_dat_i, 2851 | output reg wbm_we_o, 2852 | output reg [3:0] wbm_sel_o, 2853 | output reg wbm_stb_o, 2854 | input wbm_ack_i, 2855 | output reg wbm_cyc_o, 2856 | 2857 | // Pico Co-Processor Interface (PCPI) 2858 | output pcpi_valid, 2859 | output [31:0] pcpi_insn, 2860 | output [31:0] pcpi_rs1, 2861 | output [31:0] pcpi_rs2, 2862 | input pcpi_wr, 2863 | input [31:0] pcpi_rd, 2864 | input pcpi_wait, 2865 | input pcpi_ready, 2866 | 2867 | // IRQ interface 2868 | input [31:0] irq, 2869 | output [31:0] eoi, 2870 | 2871 | `ifdef RISCV_FORMAL 2872 | output rvfi_valid, 2873 | output [63:0] rvfi_order, 2874 | output [31:0] rvfi_insn, 2875 | output rvfi_trap, 2876 | output rvfi_halt, 2877 | output rvfi_intr, 2878 | output [ 4:0] rvfi_rs1_addr, 2879 | output [ 4:0] rvfi_rs2_addr, 2880 | output [31:0] rvfi_rs1_rdata, 2881 | output [31:0] rvfi_rs2_rdata, 2882 | output [ 4:0] rvfi_rd_addr, 2883 | output [31:0] rvfi_rd_wdata, 2884 | output [31:0] rvfi_pc_rdata, 2885 | output [31:0] rvfi_pc_wdata, 2886 | output [31:0] rvfi_mem_addr, 2887 | output [ 3:0] rvfi_mem_rmask, 2888 | output [ 3:0] rvfi_mem_wmask, 2889 | output [31:0] rvfi_mem_rdata, 2890 | output [31:0] rvfi_mem_wdata, 2891 | `endif 2892 | 2893 | // Trace Interface 2894 | output trace_valid, 2895 | output [35:0] trace_data, 2896 | 2897 | output mem_instr 2898 | ); 2899 | wire mem_valid; 2900 | wire [31:0] mem_addr; 2901 | wire [31:0] mem_wdata; 2902 | wire [ 3:0] mem_wstrb; 2903 | reg mem_ready; 2904 | reg [31:0] mem_rdata; 2905 | 2906 | wire clk; 2907 | wire resetn; 2908 | 2909 | assign clk = wb_clk_i; 2910 | assign resetn = ~wb_rst_i; 2911 | 2912 | picorv32 #( 2913 | .ENABLE_COUNTERS (ENABLE_COUNTERS ), 2914 | .ENABLE_COUNTERS64 (ENABLE_COUNTERS64 ), 2915 | .ENABLE_REGS_16_31 (ENABLE_REGS_16_31 ), 2916 | .ENABLE_REGS_DUALPORT(ENABLE_REGS_DUALPORT), 2917 | .TWO_STAGE_SHIFT (TWO_STAGE_SHIFT ), 2918 | .BARREL_SHIFTER (BARREL_SHIFTER ), 2919 | .TWO_CYCLE_COMPARE (TWO_CYCLE_COMPARE ), 2920 | .TWO_CYCLE_ALU (TWO_CYCLE_ALU ), 2921 | .COMPRESSED_ISA (COMPRESSED_ISA ), 2922 | .CATCH_MISALIGN (CATCH_MISALIGN ), 2923 | .CATCH_ILLINSN (CATCH_ILLINSN ), 2924 | .ENABLE_PCPI (ENABLE_PCPI ), 2925 | .ENABLE_MUL (ENABLE_MUL ), 2926 | .ENABLE_FAST_MUL (ENABLE_FAST_MUL ), 2927 | .ENABLE_DIV (ENABLE_DIV ), 2928 | .ENABLE_IRQ (ENABLE_IRQ ), 2929 | .ENABLE_IRQ_QREGS (ENABLE_IRQ_QREGS ), 2930 | .ENABLE_IRQ_TIMER (ENABLE_IRQ_TIMER ), 2931 | .ENABLE_TRACE (ENABLE_TRACE ), 2932 | .REGS_INIT_ZERO (REGS_INIT_ZERO ), 2933 | .MASKED_IRQ (MASKED_IRQ ), 2934 | .LATCHED_IRQ (LATCHED_IRQ ), 2935 | .PROGADDR_RESET (PROGADDR_RESET ), 2936 | .PROGADDR_IRQ (PROGADDR_IRQ ), 2937 | .STACKADDR (STACKADDR ) 2938 | ) picorv32_core ( 2939 | .clk (clk ), 2940 | .resetn (resetn), 2941 | .trap (trap ), 2942 | 2943 | .mem_valid(mem_valid), 2944 | .mem_addr (mem_addr ), 2945 | .mem_wdata(mem_wdata), 2946 | .mem_wstrb(mem_wstrb), 2947 | .mem_instr(mem_instr), 2948 | .mem_ready(mem_ready), 2949 | .mem_rdata(mem_rdata), 2950 | 2951 | .pcpi_valid(pcpi_valid), 2952 | .pcpi_insn (pcpi_insn ), 2953 | .pcpi_rs1 (pcpi_rs1 ), 2954 | .pcpi_rs2 (pcpi_rs2 ), 2955 | .pcpi_wr (pcpi_wr ), 2956 | .pcpi_rd (pcpi_rd ), 2957 | .pcpi_wait (pcpi_wait ), 2958 | .pcpi_ready(pcpi_ready), 2959 | 2960 | .irq(irq), 2961 | .eoi(eoi), 2962 | 2963 | `ifdef RISCV_FORMAL 2964 | .rvfi_valid (rvfi_valid ), 2965 | .rvfi_order (rvfi_order ), 2966 | .rvfi_insn (rvfi_insn ), 2967 | .rvfi_trap (rvfi_trap ), 2968 | .rvfi_halt (rvfi_halt ), 2969 | .rvfi_intr (rvfi_intr ), 2970 | .rvfi_rs1_addr (rvfi_rs1_addr ), 2971 | .rvfi_rs2_addr (rvfi_rs2_addr ), 2972 | .rvfi_rs1_rdata(rvfi_rs1_rdata), 2973 | .rvfi_rs2_rdata(rvfi_rs2_rdata), 2974 | .rvfi_rd_addr (rvfi_rd_addr ), 2975 | .rvfi_rd_wdata (rvfi_rd_wdata ), 2976 | .rvfi_pc_rdata (rvfi_pc_rdata ), 2977 | .rvfi_pc_wdata (rvfi_pc_wdata ), 2978 | .rvfi_mem_addr (rvfi_mem_addr ), 2979 | .rvfi_mem_rmask(rvfi_mem_rmask), 2980 | .rvfi_mem_wmask(rvfi_mem_wmask), 2981 | .rvfi_mem_rdata(rvfi_mem_rdata), 2982 | .rvfi_mem_wdata(rvfi_mem_wdata), 2983 | `endif 2984 | 2985 | .trace_valid(trace_valid), 2986 | .trace_data (trace_data) 2987 | ); 2988 | 2989 | localparam IDLE = 2'b00; 2990 | localparam WBSTART = 2'b01; 2991 | localparam WBEND = 2'b10; 2992 | 2993 | reg [1:0] state; 2994 | 2995 | wire we; 2996 | assign we = (mem_wstrb[0] | mem_wstrb[1] | mem_wstrb[2] | mem_wstrb[3]); 2997 | 2998 | always @(posedge wb_clk_i) begin 2999 | if (wb_rst_i) begin 3000 | wbm_adr_o <= 0; 3001 | wbm_dat_o <= 0; 3002 | wbm_we_o <= 0; 3003 | wbm_sel_o <= 0; 3004 | wbm_stb_o <= 0; 3005 | wbm_cyc_o <= 0; 3006 | state <= IDLE; 3007 | end else begin 3008 | case (state) 3009 | IDLE: begin 3010 | if (mem_valid) begin 3011 | wbm_adr_o <= mem_addr; 3012 | wbm_dat_o <= mem_wdata; 3013 | wbm_we_o <= we; 3014 | wbm_sel_o <= mem_wstrb; 3015 | 3016 | wbm_stb_o <= 1'b1; 3017 | wbm_cyc_o <= 1'b1; 3018 | state <= WBSTART; 3019 | end else begin 3020 | mem_ready <= 1'b0; 3021 | 3022 | wbm_stb_o <= 1'b0; 3023 | wbm_cyc_o <= 1'b0; 3024 | wbm_we_o <= 1'b0; 3025 | end 3026 | end 3027 | WBSTART:begin 3028 | if (wbm_ack_i) begin 3029 | mem_rdata <= wbm_dat_i; 3030 | mem_ready <= 1'b1; 3031 | 3032 | state <= WBEND; 3033 | 3034 | wbm_stb_o <= 1'b0; 3035 | wbm_cyc_o <= 1'b0; 3036 | wbm_we_o <= 1'b0; 3037 | end 3038 | end 3039 | WBEND: begin 3040 | mem_ready <= 1'b0; 3041 | 3042 | state <= IDLE; 3043 | end 3044 | default: 3045 | state <= IDLE; 3046 | endcase 3047 | end 3048 | end 3049 | endmodule 3050 | --------------------------------------------------------------------------------