diff --git a/README.md b/README.md new file mode 100644 index 00000000..b27ab3b2 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# RI5CY: RISC-V Core + +RI5CY is a small 4-stage RISC-V core. It starte its life as a +fork of the OR10N cpu core that is based on the OpenRISC ISA. + +RI5CY fully implements the RV32I instruction set, the multiply instruction from +RV32M and many custom instruction set extensions that improve its performance +for signal processing applications. + +The core was developed as part of the [PULP platform](http://pulp.ethz.ch/) for +energy-efficient computing and is currently used as the processing core for +PULP and PULPino. + +## Documentation + +A datasheet that explains the most important features of the core can be found +in `docs/datasheet/`. + +It is written using LaTeX and can be generated as follows + + make all + diff --git a/controller.sv b/controller.sv index 06782fc7..d1b9f97b 100644 --- a/controller.sv +++ b/controller.sv @@ -71,7 +71,8 @@ module riscv_controller input logic trap_hit_i, // a trap was hit, so we have to flush EX and WB - output logic save_pc_id_o, + output logic exc_save_id_o, + output logic exc_restore_id_o, // Debug Unit Signals input logic dbg_stall_i, // Pipeline stall is requested @@ -158,23 +159,24 @@ module riscv_controller always_comb begin // Default values - instr_req_o = 1'b1; + instr_req_o = 1'b1; - exc_ack_o = 1'b0; - save_pc_id_o = 1'b0; + exc_ack_o = 1'b0; + exc_save_id_o = 1'b0; + exc_restore_id_o = 1'b0; - pc_mux_o = `PC_BOOT; - pc_set_o = 1'b0; - jump_done = jump_done_q; + pc_mux_o = `PC_BOOT; + pc_set_o = 1'b0; + jump_done = jump_done_q; - ctrl_fsm_ns = ctrl_fsm_cs; + ctrl_fsm_ns = ctrl_fsm_cs; - core_busy_o = 1'b1; - is_decoding_o = 1'b0; + core_busy_o = 1'b1; + is_decoding_o = 1'b0; - halt_if_o = 1'b0; - halt_id_o = 1'b0; - dbg_trap_o = 1'b0; + halt_if_o = 1'b0; + halt_id_o = 1'b0; + dbg_trap_o = 1'b0; unique case (ctrl_fsm_cs) // We were just reset, wait for fetch_enable @@ -227,7 +229,7 @@ module riscv_controller // TODO: This assumes that the pipeline is always flushed before // going to sleep. - save_pc_id_o = 1'b1; + exc_save_id_o = 1'b1; end end @@ -266,7 +268,7 @@ module riscv_controller exc_ack_o = 1'b1; halt_id_o = 1'b1; // we don't want to propagate this instruction to EX - save_pc_id_o = 1'b1; + exc_save_id_o = 1'b1; // we don't have to change our current state here as the prefetch // buffer is automatically invalidated, thus the next instruction @@ -276,8 +278,9 @@ module riscv_controller end if (eret_insn_i) begin - pc_mux_o = `PC_ERET; - pc_set_o = 1'b1; + pc_mux_o = `PC_ERET; + pc_set_o = 1'b1; + exc_restore_id_o = 1'b1; end // handle WFI instruction, flush pipeline and (potentially) go to diff --git a/cs_registers.sv b/cs_registers.sv index 7c4ea95f..6069003a 100644 --- a/cs_registers.sv +++ b/cs_registers.sv @@ -55,10 +55,11 @@ module riscv_cs_registers // Interrupts output logic irq_enable_o, - output logic [31:0] epcr_o, + output logic [31:0] mepc_o, input logic [31:0] curr_pc_id_i, - input logic save_pc_id_i, + input logic exc_save_i, + input logic exc_restore_i, input logic [5:0] exc_cause_i, input logic save_exc_cause_i, @@ -115,17 +116,16 @@ module riscv_cs_registers logic is_pcer; logic is_pcmr; - // Generic CSRs - logic [31:0] mepc_q, mepc_n; - // CSR update logic logic [31:0] csr_wdata_int; logic [31:0] csr_rdata_int; logic csr_we_int; // Interrupt control signals - logic irq_enable, irq_enable_n; - logic [5:0] exc_cause, exc_cause_n; + logic [31:0] mepc_q, mepc_n; + logic [ 0:0] mestatus_q, mestatus_n; + logic [ 0:0] mstatus_q, mstatus_n; + logic [ 5:0] exc_cause, exc_cause_n; //////////////////////////////////////////// @@ -144,7 +144,7 @@ module riscv_cs_registers case (csr_addr_i) // mstatus: always M-mode, contains IE bit - 12'h300: csr_rdata_int = {29'b0, 2'b11, irq_enable}; + 12'h300: csr_rdata_int = {29'b0, 2'b11, mstatus_q}; // mepc: exception program counter 12'h341: csr_rdata_int = mepc_q; @@ -165,6 +165,8 @@ module riscv_cs_registers 12'h7B4: csr_rdata_int = hwlp_start_i[1]; 12'h7B5: csr_rdata_int = hwlp_end_i[1]; 12'h7B6: csr_rdata_int = hwlp_cnt_i[1]; + + 12'h7C0: csr_rdata_int = {29'b0, 2'b11, mestatus_q}; endcase end @@ -173,14 +175,15 @@ module riscv_cs_registers always_comb begin mepc_n = mepc_q; - irq_enable_n = irq_enable; + mestatus_n = mestatus_q; + mstatus_n = mstatus_q; exc_cause_n = exc_cause; hwlp_we_o = '0; hwlp_regid_o = '0; case (csr_addr_i) // mstatus: IE bit - 12'h300: if (csr_we_int) irq_enable_n = csr_wdata_int[0]; + 12'h300: if (csr_we_int) mstatus_n = csr_wdata_int[0]; // mepc: exception program counter 12'h341: if (csr_we_int) mepc_n = csr_wdata_int; @@ -194,7 +197,24 @@ module riscv_cs_registers 12'h7B4: if (csr_we_int) begin hwlp_we_o = 3'b001; hwlp_regid_o = 1'b1; end 12'h7B5: if (csr_we_int) begin hwlp_we_o = 3'b010; hwlp_regid_o = 1'b1; end 12'h7B6: if (csr_we_int) begin hwlp_we_o = 3'b100; hwlp_regid_o = 1'b1; end + + // mestatus: machine exception status + 12'h7C0: if (csr_we_int) mestatus_n = csr_wdata_int[0]; endcase + + // exception controller gets priority over other writes + if (exc_save_i) begin + mepc_n = curr_pc_id_i; + mestatus_n = mstatus_q; + mstatus_n = 1'b0; + end + + if (save_exc_cause_i) + exc_cause_n = exc_cause_i; + + if (exc_restore_i) begin + mstatus_n = mestatus_q; + end end assign hwlp_data_o = csr_wdata_int; @@ -231,8 +251,8 @@ module riscv_cs_registers // directly output some registers - assign irq_enable_o = irq_enable; - assign epcr_o = mepc_q; + assign irq_enable_o = mstatus_q[0]; + assign mepc_o = mepc_q; // actual registers @@ -240,25 +260,20 @@ module riscv_cs_registers begin if (rst_n == 1'b0) begin - irq_enable <= 1'b0; + mstatus_q <= '0; mepc_q <= '0; + mestatus_q <= '0; exc_cause <= '0; end else begin // update CSRs - irq_enable <= irq_enable_n; + mstatus_q <= mstatus_n; - // exception controller gets priority over other writes - if (save_pc_id_i == 1'b1) - mepc_q <= curr_pc_id_i; - else - mepc_q <= mepc_n; + mepc_q <= mepc_n; + mestatus_q <= mestatus_n; - if (save_exc_cause_i) - exc_cause <= exc_cause_i; - else - exc_cause <= exc_cause_n; + exc_cause <= exc_cause_n; end end diff --git a/docs/datasheet/content/csr.tex b/docs/datasheet/content/csr.tex index 92dde154..83b598b4 100644 --- a/docs/datasheet/content/csr.tex +++ b/docs/datasheet/content/csr.tex @@ -18,9 +18,10 @@ as possible and avoid any overhead that we do not explicitely need. 00 & 11 & 01 & 000001 & 0x341 & MEPC & R/W & Machine exception program counter \\ \hline 00 & 11 & 01 & 000010 & 0x342 & MCAUSE & R/W & Machine trap cause \\ \hline 01 & 11 & 00 & 0XXXXX & 0x780 - 0x79F & PCCRs & R/W & Performance Counter Counter Registers \\ \hline - 01 & 11 & 10 & 200000 & 0x7A0 & PCER & R/W & Performance Counter Enable Register \\ \hline + 01 & 11 & 10 & 100000 & 0x7A0 & PCER & R/W & Performance Counter Enable Register \\ \hline 01 & 11 & 10 & 100001 & 0x7A1 & PCMR & R/W & Performance Counter Mode Register \\ \hline 01 & 11 & 10 & 110XXX & 0x7B0 - 0x7B6 & HWLP & R/W & Hardware Loop Registers \\ \hline + 01 & 11 & 10 & 111000 & 0x7C0 & MESTATUS & R/W & Machine exception Status Register \\ \hline 11 & 11 & 00 & 000000 & 0xF00 & MCPUID & R & CPU description \\ \hline 11 & 11 & 00 & 000001 & 0xF01 & MIMPID & R & Vendor ID and version number \\ \hline 11 & 11 & 00 & 010000 & 0xF10 & MHARTID & R & Hardware Thread ID \\ \bottomrule @@ -41,6 +42,28 @@ as possible and avoid any overhead that we do not explicitely need. } Note that \signal{PRV[1:0]} is statically \signal{2'b11} and cannot be altered (read-only). +When en exception is encountered, \signal{Interrupt Enable} will be set to +\signal{1'b0}. When the \signal{eret} instruction is executed, the original +value of \signal{Interrupt Enable} will be restored, as \signal{MESTATUS} will +replace \signal{MSTATUS}. +If you want to enable interrupt handling in your exception hanlder, set the +\signal{Interrupt Enable} to \signal{1'b1} inside your handler code. + +\subsection{MESTATUS} +\csrDesc{0x7C0}{0x0000\_0006}{MESTATUS}{ + \begin{bytefield}[endianness=big,bitheight=60pt]{32} + \bitheader{31,2,1,0} \\ + \bitbox{29}{ Unused } + \bitbox{2}{\rotatebox{90}{\tiny PRV[1:0] }} + \bitbox{1}{\rotatebox{90}{\tiny Interrupt Enable }} + \end{bytefield} +} + +Note that \signal{PRV[1:0]} is statically \signal{2'b11} and cannot be altered (read-only). + +When an exception is encountered, the current value of \signal{MSTATUS} is saved +in \signal{MESTATUS}. When an \instr{eret} instruction is executed, the value +from \signal{MESTATUS} replaces the \signal{MSTATUS} register. \subsection{MEPC} @@ -52,9 +75,9 @@ Note that \signal{PRV[1:0]} is statically \signal{2'b11} and cannot be altered ( } When an exception is encountered, the current program counter is saved in -\signal{mepc} and the core jumps to the exception address. -When an \instr{eret} instruction is executed, the value from \signal{mepc} -replaces the current program counter. +\signal{MEPC}, and the core jumps to the exception address. When an \instr{eret} +instruction is executed, the value from \signal{MEPC} replaces the current +program counter. \subsection{MCAUSE} \csrDesc{0x341}{0x0000\_0000}{MCAUSE}{ diff --git a/docs/datasheet/content/exceptions.tex b/docs/datasheet/content/exceptions.tex index 67eca5ca..afdb2d1e 100644 --- a/docs/datasheet/content/exceptions.tex +++ b/docs/datasheet/content/exceptions.tex @@ -29,7 +29,15 @@ exception/interrupt. interrupt lines. Interrupts can only be enabled/disabled on a global basis and not individually. It is assumed that there is an event/interrupt controller outside of the core that performs masking and buffering of the interrupt lines. -The global interrupt enable is done via the CSR register \signal{mstatus}. +The global interrupt enable is done via the CSR register \signal{MSTATUS}. + +If multiple interrupts arrive in the same cycle, the interrupt with the lowest +number will be executed first. As soon as IRQs are re-enabled, either after an +\signal{eret} or an explicit enable, the interrupt with lowest number will be +executed. +This means that it is important to clear the interrupt line before re-enabling +interrupts, as otherwise the same interrupt handler could be called over and +over again. \section{Exceptions} @@ -38,16 +46,21 @@ exceptions and ecall instruction exceptions can not be disabled and are always active. The illegal instruction exception and the load and store invalid memory access -exceptions are precise exceptions, i.e. the value of \signal{mepc} will be the +exceptions are precise exceptions, i.e. the value of \signal{MEPC} will be the instruction address that caused it. \section{Handling} -\rvcore does not support nested interrupt/exception handling. Exceptions inside -interrupt/exception handlers are ignored and thus a user must ensure that such -a situation does not happen, as otherwise the behaviour is undefined. +\rvcore does support nested interrupt/exception handling. Exceptions inside +interrupt/exception handlers cause another exception, thus exceptions during the +critical part of your exception handlers, i.e. before having saved the +\signal{MEPC} and \signal{MESTATUS} registers, will cause those register to be +overwritten. +Interrupts during interrupt/exception handlers are disabled by default, but can +be explicitely enabled if desired. Upon executing an \instr{eret} instruction, the core jumps to the program -counter saved in the CSR register \signal{mepc}. When entering an -interrupt/exception handler, the core sets \signal{mepc} to the current program -counter. +counter saved in the CSR register \signal{MEPC} and restores the value of +register \signal{MESTATUS} to \signal{MSTATUS}. When entering an +interrupt/exception handler, the core sets \signal{MEPC} to the current program +counter and saves the current value of \signal{MSTATUS} in \signal{MESTATUS}. diff --git a/docs/datasheet/content/hwloop.tex b/docs/datasheet/content/hwloop.tex index 2faefbe2..775eaf70 100644 --- a/docs/datasheet/content/hwloop.tex +++ b/docs/datasheet/content/hwloop.tex @@ -13,6 +13,9 @@ the loop body is executed. RI5CY contains two hardware loop register sets, each of them can store these three values. If the end address of the two hardware loops is identical, loop 0 has higher priority and only the loop counter for hardware loop 0 is decremented. +As soon as the counter of loop 0 reaches 1 at an end address, meaning it is +decremented to 0 now, loop 1 gets active too. In this case, both counters will +be decremented and the core jumps to the start of loop 1. The instructions described below are used to setup the hardware loop registers. Note that the minimum loop size is two instructions. diff --git a/docs/datasheet/content/pipeline.tex b/docs/datasheet/content/pipeline.tex new file mode 100644 index 00000000..0a9f02af --- /dev/null +++ b/docs/datasheet/content/pipeline.tex @@ -0,0 +1,44 @@ +\chapter{Pipeline} +\label{chap:pipeline} + +\rvcore has a fully independent pipeline, meaning that whenever possible data +will propagate through the pipeline and therefor does not suffer from any +unneeded stalls. + +The pipeline design is easily extendable to incorporate out-of-order +completion. E.g. it would be possible to complete an instruction that only +needs the EX stage before the WB stage, that is currently blocked waiting for +an rvalid, is ready. +Currently this is not done in \rvcore, but might be added in the future. + +Figure~\ref{fig:pipeline} shows the control signals relevant for the pipeline +operation. Running from right to left are the main control signals, the +\signal{ready} signals of each pipeline stage. +Each pipeline stage has two control inputs: an enable and a clear. The enable +activates the pipeline stage and the core moves forward by one instruction. The +clear removes the instruction from the pipeline stage as it is completed. +At every pipeline stage, when the \signal{ready} coming from the stage to the +right is high, but the valid signal of the stage is low, the stage is cleared. +If the valid signal is high, it is enabled. + +Going from right to left every stage is independent, no stage depends on the +stage on its left. Going from left to right every stage depends on its right +neighbor and can only continue when it is ready. +This means that in addition that a single stage has to be ready, also the stage +on its right has to be ready to move on. + +\begin{figure}[H] + \centering + \includegraphics[width=0.9\textwidth]{./figures/pipeline} + \caption{\rvcore Pipeline.} + \label{fig:pipeline} +\end{figure} + + + +\begin{boxnote} +In contrast to \orion there is no global stall controller any more, instead +every stage manages its own dependencies. The main controller of \rvcore is now +only responsible for control flow operations, i.e. flushing the pipe, branches, +jumps and exceptions. +\end{boxnote} diff --git a/docs/datasheet/datasheet.tex b/docs/datasheet/datasheet.tex index f36aa660..308cbca1 100644 --- a/docs/datasheet/datasheet.tex +++ b/docs/datasheet/datasheet.tex @@ -37,6 +37,7 @@ \input{./content/mac.tex} \input{./content/aluext.tex} \input{./content/hwloop.tex} +\input{./content/pipeline.tex} \input{./content/rf.tex} \input{./content/csr.tex} \input{./content/perfcounters.tex} diff --git a/docs/datasheet/figures_raw/pipeline.obj b/docs/datasheet/figures_raw/pipeline.obj new file mode 100644 index 00000000..a4be00c6 --- /dev/null +++ b/docs/datasheet/figures_raw/pipeline.obj @@ -0,0 +1,641 @@ +%TGIF 4.2.5-QPL +state(0,37,100.000,0,0,0,32,1,16,2,2,1,0,0,0,1,1,'Helvetica-Bold',1,97920,0,0,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,5760,0). +% +% @(#)$Header$ +% %W% +% +unit("1 pixel/pixel"). +color_info(66,65535,0,[ + "black", 0, 0, 0, 0, 0, 0, 1, + "white", 65535, 65535, 65535, 65535, 65535, 65535, 1, + "#F0F0F0", 61680, 61680, 61680, 61440, 61440, 61440, 1, + "#C8C8C8", 51400, 51400, 51400, 51200, 51200, 51200, 1, + "#505050", 20560, 20560, 20560, 20480, 20480, 20480, 1, + "#282828", 10280, 10280, 10280, 10240, 10240, 10240, 1, + "#FF0000", 65535, 0, 0, 65280, 0, 0, 1, + "#0000FF", 0, 0, 65535, 0, 0, 65280, 1, + "#00FF00", 0, 65535, 0, 0, 65280, 0, 1, + "#009000", 0, 37008, 0, 0, 36864, 0, 1, + "#1F407A", 7967, 16448, 31354, 7936, 16384, 31232, 1, + "#3C5A0F", 15420, 23130, 3855, 15360, 23040, 3840, 1, + "#0069B4", 0, 26985, 46260, 0, 26880, 46080, 1, + "#71791C", 29041, 31097, 7196, 28928, 30976, 7168, 1, + "#91056A", 37265, 1285, 27242, 37120, 1280, 27136, 1, + "#6F6F6E", 28527, 28527, 28270, 28416, 28416, 28160, 1, + "#A8322D", 43176, 12850, 11565, 43008, 12800, 11520, 1, + "#007A92", 0, 31354, 37522, 0, 31232, 37376, 1, + "#956013", 38293, 24672, 4883, 38144, 24576, 4864, 1, + "#82BE1E", 33410, 48830, 7710, 33280, 48640, 7680, 1, + "#758fbd", 30069, 36751, 48573, 29952, 36608, 48384, 1, + "#8eab63", 36494, 43947, 25443, 36352, 43776, 25344, 1, + "#6cacd9", 27756, 44204, 55769, 27648, 44032, 55552, 1, + "#b4ba72", 46260, 47802, 29298, 46080, 47616, 29184, 1, + "#c967ae", 51657, 26471, 44718, 51456, 26368, 44544, 1, + "#b8b8b6", 47288, 47288, 46774, 47104, 47104, 46592, 1, + "#d48985", 54484, 35209, 34181, 54272, 35072, 34048, 1, + "#65b9c9", 25957, 47545, 51657, 25856, 47360, 51456, 1, + "#c9a571", 51657, 42405, 29041, 51456, 42240, 28928, 1, + "#bbde81", 48059, 57054, 33153, 47872, 56832, 33024, 1, + "#a5b7d6", 42405, 47031, 54998, 42240, 46848, 54784, 1, + "#b8cc99", 47288, 52428, 39321, 47104, 52224, 39168, 1, + "#a2cbe8", 41634, 52171, 59624, 41472, 51968, 59392, 1, + "#d2d6a5", 53970, 54998, 42405, 53760, 54784, 42240, 1, + "#de9ecc", 57054, 40606, 52428, 56832, 40448, 52224, 1, + "#d4d4d2", 54484, 54484, 53970, 54272, 54272, 53760, 1, + "#e6b5b3", 59110, 46517, 46003, 58880, 46336, 45824, 1, + "#9bd3de", 39835, 54227, 57054, 39680, 54016, 56832, 1, + "#dec6a4", 57054, 50886, 42148, 56832, 50688, 41984, 1, + "#d5ebb0", 54741, 60395, 45232, 54528, 60160, 45056, 1, + "#b3cde3", 46003, 52685, 58339, 45824, 52480, 58112, 1, + "#bae4bc", 47802, 58596, 48316, 47616, 58368, 48128, 1, + "#edf8fb", 60909, 63736, 64507, 60672, 63488, 64256, 1, + "#ffffcc", 65535, 65535, 52428, 65280, 65280, 52224, 1, + "magenta", 65535, 0, 65535, 65535, 0, 65535, 1, + "#f0f9e8", 61680, 63993, 59624, 61440, 63744, 59392, 1, + "#feebe2", 65278, 60395, 58082, 65024, 60160, 57856, 1, + "cyan", 0, 65535, 65535, 0, 65535, 65535, 1, + "#fecc5c", 65278, 52428, 23644, 65024, 52224, 23552, 1, + "yellow", 65535, 65535, 0, 65535, 65535, 0, 1, + "red", 65535, 0, 0, 65535, 0, 0, 1, + "green", 0, 65535, 0, 0, 65535, 0, 1, + "blue", 0, 0, 65535, 0, 0, 65535, 1, + "pink", 65535, 49344, 52171, 65535, 49344, 52171, 1, + "CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1, + "DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1, + "#FF4D08", 65535, 19789, 2056, 65280, 19712, 2048, 1, + "#FF6437", 65535, 25700, 14135, 65280, 25600, 14080, 1, + "#7F321B", 32639, 12850, 6939, 32512, 12800, 6912, 1, + "#FF8080", 65535, 32896, 32896, 65280, 32768, 32768, 1, + "#FF8A7E", 65535, 35466, 32382, 65280, 35328, 32256, 1, + "#FFC37C", 65535, 50115, 31868, 65280, 49920, 31744, 1, + "#7F4A0D", 32639, 19018, 3341, 32512, 18944, 3328, 1, + "#DE82FF", 57054, 33410, 65535, 56832, 33280, 65280, 1, + "#EFB8FF", 61423, 47288, 65535, 61184, 47104, 65280, 1, + "#6F367F", 28527, 13878, 32639, 28416, 13824, 32512, 1 +]). +script_frac("0.6"). +fg_bg_colors('#A8322D','white'). +dont_reencode("FFDingbests:ZapfDingbats"). +objshadow_info('#c0c0c0',2,2). +rotate_pivot(0,0,0,0). +spline_tightness(1). +page(1,"",1,''). +box('#EFB8FF','',288,256,320,560,1,2,0,288070,0,0,0,0,0,'2',0,[ +]). +box('#EFB8FF','',592,256,624,560,1,2,0,288062,0,0,0,0,0,'2',0,[ +]). +box('#EFB8FF','',888,400,920,560,1,2,0,288031,0,0,0,0,0,'2',0,[ +]). +rcbox('#f0f9e8','',332,256,580,616,1,1,0,0,16,287695,0,0,0,0,'1',0,[ +]). +rcbox('#f0f9e8','',636,256,876,616,1,1,0,0,16,287722,0,0,0,0,'1',0,[ +]). +rcbox('#f0f9e8','',932,256,1052,616,1,1,0,0,16,287742,0,0,0,0,'1',0,[ +]). +rcbox('#f0f9e8','',24,256,276,616,1,1,0,0,16,287635,0,0,0,0,'1',0,[ +]). +rcbox('#d4d4d2','',24,256,276,616,0,1,1,0,16,287685,0,0,0,0,'1',0,[ +]). +poly('black','',2,[ + 820,280,820,192],1,1,1,286345,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',816,170,1,1,1,40,17,286346,14,3,0,0,0,0,2,40,17,0,0,"",0,0,0,0,184,'',[ +minilines(40,17,0,0,1,0,0,[ +mini_line(40,14,3,0,0,0,[ +str_block(0,40,14,3,0,-1,0,0,0,[ +str_seg('#0069B4','Courier-Bold',1,97920,40,14,3,0,-1,0,0,0,0,0, + "addr")]) +]) +])]). +text('black',960,170,1,1,1,60,17,286404,14,3,0,0,0,0,2,60,17,0,0,"",0,0,0,0,184,'',[ +minilines(60,17,0,0,1,0,0,[ +mini_line(60,14,3,0,0,0,[ +str_block(0,60,14,3,0,-1,0,0,0,[ +str_seg('#0069B4','Courier-Bold',1,97920,60,14,3,0,-1,0,0,0,0,0, + "rvalid")]) +]) +])]). +text('black',872,170,1,1,1,50,17,286468,14,3,0,0,0,0,2,50,17,0,0,"",0,0,0,0,184,'',[ +minilines(50,17,0,0,1,0,0,[ +mini_line(50,14,3,0,0,0,[ +str_block(0,50,14,3,0,-1,0,0,0,[ +str_seg('#0069B4','Courier-Bold',1,97920,50,14,3,0,-1,0,0,0,0,0, + "grant")]) +]) +])]). +rcbox('#0069B4','',784,136,1024,192,0,1,1,0,16,286710,0,0,0,0,'1',0,[ +]). +text('black',888,142,1,1,1,127,23,286718,18,5,0,0,0,0,2,127,23,0,0,"",0,0,0,0,160,'',[ +minilines(127,23,0,0,1,0,0,[ +mini_line(127,18,5,0,0,0,[ +str_block(0,127,18,5,0,-1,0,0,0,[ +str_seg('#0069B4','Helvetica-Bold',1,115200,127,18,5,0,-1,0,0,0,0,0, + "Data Interface")]) +]) +])]). +box('black','',12,224,1064,664,0,1,1,286736,0,0,0,0,0,'1',0,[ +]). +text('black',184,170,1,1,1,40,17,286355,14,3,0,0,0,0,2,40,17,0,0,"",0,0,0,0,184,'',[ +minilines(40,17,0,0,1,0,0,[ +mini_line(40,14,3,0,0,0,[ +str_block(0,40,14,3,0,-1,0,0,0,[ +str_seg('#0069B4','Courier-Bold',1,97920,40,14,3,0,-1,0,0,0,0,0, + "addr")]) +]) +])]). +text('black',120,170,1,1,1,60,17,286569,14,3,0,0,0,0,2,60,17,0,0,"",0,0,0,0,184,'',[ +minilines(60,17,0,0,1,0,0,[ +mini_line(60,14,3,0,0,0,[ +str_block(0,60,14,3,0,-1,0,0,0,[ +str_seg('#0069B4','Courier-Bold',1,97920,60,14,3,0,-1,0,0,0,0,0, + "rvalid")]) +]) +])]). +rcbox('#0069B4','',56,136,264,192,0,1,1,0,16,286711,0,0,0,0,'1',0,[ +]). +text('black',160,142,1,1,1,181,23,286715,18,5,0,0,0,0,2,181,23,0,0,"",0,0,0,0,160,'',[ +minilines(181,23,0,0,1,0,0,[ +mini_line(181,18,5,0,0,0,[ +str_block(0,181,18,5,0,-1,0,0,0,[ +str_seg('#0069B4','Helvetica-Bold',1,115200,181,18,5,0,-1,0,0,0,0,0, + "Instruction Interface")]) +]) +])]). +box('#6F367F','',288,256,320,560,0,2,1,283037,0,0,0,0,0,'2',0,[ +]). +text('black',294,415,2,0,1,20,35,283038,14,3,0,0,0,0,2,20,34,0,0,"",0,1,0,0,429,'',[ + 294,415,294,415,314,449,1000,0,0,1022.73,0,4,293,414,315,450],[ +minilines(20,34,0,0,0,0,0,[ +mini_line(20,14,3,0,0,0,[ +str_block(0,20,14,3,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,20,14,3,0,-1,0,0,0,0,0, + "IF")]) +]), +mini_line(20,14,3,0,0,0,[ +str_block(0,20,14,3,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,20,14,3,0,-1,0,0,0,0,0, + "ID")]) +]) +])]). +box('#6F367F','',592,256,624,560,0,2,1,283031,0,0,0,0,0,'2',0,[ +]). +text('black',598,415,2,0,1,20,34,283032,14,3,0,0,0,0,2,20,34,0,0,"",0,0,0,0,429,'',[ +minilines(20,34,0,0,0,0,0,[ +mini_line(20,14,3,0,0,0,[ +str_block(0,20,14,3,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,20,14,3,0,-1,0,0,0,0,0, + "ID")]) +]), +mini_line(20,14,3,0,0,0,[ +str_block(0,20,14,3,0,0,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,20,14,3,0,0,0,0,0,0,0, + "EX")]) +]) +])]). +box('#6F367F','',888,400,920,560,0,2,1,283042,0,0,0,0,0,'2',0,[ +]). +text('black',894,415,2,0,1,20,34,283043,14,3,0,0,0,0,2,20,34,0,0,"",0,0,0,0,429,'',[ +minilines(20,34,0,0,0,0,0,[ +mini_line(20,14,3,0,0,0,[ +str_block(0,20,14,3,0,0,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,20,14,3,0,0,0,0,0,0,0, + "EX")]) +]), +mini_line(20,14,3,0,0,0,[ +str_block(0,20,14,3,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,20,14,3,0,-1,0,0,0,0,0, + "WB")]) +]) +])]). +poly('black','',2,[ + 172,280,172,192],1,1,1,287533,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +poly('black','',2,[ + 116,192,116,280],1,1,1,287631,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +rcbox('#d4d4d2','',332,256,580,616,0,1,1,0,16,287693,0,0,0,0,'1',0,[ +]). +rcbox('#d4d4d2','',636,256,876,616,0,1,1,0,16,287738,0,0,0,0,'1',0,[ +]). +rcbox('#d4d4d2','',932,256,1052,616,0,1,1,0,16,287749,0,0,0,0,'1',0,[ +]). +poly('#6F367F','',3,[ + 296,560,304,548,312,560],0,2,1,288021,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('#6F367F','',3,[ + 600,560,608,548,616,560],0,2,1,288025,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('#6F367F','',3,[ + 896,560,904,548,912,560],0,2,1,288028,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +text('#6F367F',376,554,1,1,1,80,17,288303,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,568,'',[ +minilines(80,17,0,0,1,0,0,[ +mini_line(80,14,3,0,0,0,[ +str_block(0,80,14,3,0,0,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,80,14,3,0,0,0,0,0,0,0, + "id_ready")]) +]) +])]). +text('#6F367F',680,554,1,1,1,80,17,288352,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,568,'',[ +minilines(80,17,0,0,1,0,0,[ +mini_line(80,14,3,0,0,0,[ +str_block(0,80,14,3,0,0,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,80,14,3,0,0,0,0,0,0,0, + "ex_ready")]) +]) +])]). +text('#6F367F',980,554,1,1,1,80,17,288361,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,568,'',[ +minilines(80,17,0,0,1,0,0,[ +mini_line(80,14,3,0,0,0,[ +str_block(0,80,14,3,0,0,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,80,14,3,0,0,0,0,0,0,0, + "wb_ready")]) +]) +])]). +poly('black','',3,[ + 496,384,496,560,472,560],1,2,1,288369,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('black','',2,[ + 728,576,472,576],1,2,1,288370,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +text('#6F367F',456,410,1,1,1,60,17,288372,14,3,0,0,0,0,-65534,60,17,0,0,"",0,0,0,0,424,'',[ +minilines(60,17,0,0,1,0,0,[ +mini_line(60,14,3,0,0,0,[ +str_block(0,60,14,3,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,60,14,3,0,-1,0,0,0,0,0, + "!stall")]) +]) +])]). +text('#6F367F',744,402,1,1,1,70,17,288380,14,3,0,0,0,0,-65534,70,17,0,0,"",0,0,0,0,416,'',[ +minilines(70,17,0,0,1,0,0,[ +mini_line(70,14,3,0,0,0,[ +str_block(0,70,14,3,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,70,14,3,0,-1,0,0,0,0,0, + "granted")]) +]) +])]). +text('#6F367F',988,402,1,1,1,60,17,288385,14,3,0,0,0,0,-65534,60,17,0,0,"",0,0,0,0,416,'',[ +minilines(60,17,0,0,1,0,0,[ +mini_line(60,14,3,0,0,0,[ +str_block(0,60,14,3,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,60,14,3,0,-1,0,0,0,0,0, + "rvalid")]) +]) +])]). +poly('black','',2,[ + 1028,576,776,576],1,2,1,288388,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('#3C5A0F','',3,[ + 424,576,424,608,464,608],0,2,1,288395,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('#3C5A0F','',4,[ + 448,608,568,608,568,520,592,520],1,2,1,288396,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +text('#6F367F',520,586,1,1,1,80,17,288398,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,600,'',[ +minilines(80,17,0,0,1,0,0,[ +mini_line(80,14,3,0,0,0,[ +str_block(0,80,14,3,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,80,14,3,0,-1,0,0,0,0,0, + "id_valid")]) +]) +])]). +poly('#3C5A0F','',3,[ + 728,576,728,608,752,608],0,2,1,288403,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('#3C5A0F','',4,[ + 736,608,864,608,864,520,888,520],1,2,1,288404,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +text('#6F367F',816,586,1,1,1,80,17,288405,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,600,'',[ +minilines(80,17,0,0,1,0,0,[ +mini_line(80,14,3,0,0,0,[ +str_block(0,80,14,3,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,80,14,3,0,-1,0,0,0,0,0, + "ex_valid")]) +]) +])]). +poly('#3C5A0F','',3,[ + 40,568,40,608,168,608],0,2,1,288407,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('#3C5A0F','',4,[ + 160,608,256,608,256,520,288,520],1,2,1,288408,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +text('#6F367F',208,586,1,1,1,80,17,288409,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,600,'',[ +minilines(80,17,0,0,1,0,0,[ +mini_line(80,14,3,0,0,0,[ +str_block(0,80,14,3,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,80,14,3,0,-1,0,0,0,0,0, + "if_valid")]) +]) +])]). +text('#6F367F',80,546,1,1,1,80,17,288418,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,560,'',[ +minilines(80,17,0,0,1,0,0,[ +mini_line(80,14,3,0,0,0,[ +str_block(0,80,14,3,0,0,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,80,14,3,0,0,0,0,0,0,0, + "if_ready")]) +]) +])]). +rcbox('#bbde81','',80,280,208,432,1,2,0,0,10,288422,0,0,0,0,'2',0,[ +]). +poly('#009000','',3,[ + 136,432,144,420,152,432],0,2,1,288423,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +text('black',144,296,2,1,1,101,58,288424,24,5,0,0,0,0,2,101,58,0,0,"",0,0,0,0,320,'',[ +minilines(101,58,0,0,1,0,0,[ +mini_line(101,24,5,0,0,0,[ +str_block(0,101,24,5,0,-2,0,0,0,[ +str_seg('black','Helvetica-Bold',1,138240,101,24,5,0,-2,0,0,0,0,0, + "Prefetch")]) +]), +mini_line(75,24,5,0,0,0,[ +str_block(0,75,24,5,0,-1,0,0,0,[ +str_seg('black','Helvetica-Bold',1,138240,75,24,5,0,-1,0,0,0,0,0, + "Buffer")]) +]) +])]). +rcbox('#009000','',80,280,208,432,0,2,1,0,10,288425,0,0,0,0,'2',0,[ +]). +text('#6F367F',152,458,1,1,1,50,17,288428,14,3,0,0,0,0,-65534,50,17,0,0,"",0,0,0,0,472,'',[ +minilines(50,17,0,0,1,0,0,[ +mini_line(50,14,3,0,0,0,[ +str_block(0,50,14,3,0,-1,0,0,0,[ +str_seg('black','Courier-Bold',1,97920,50,14,3,0,-1,0,0,0,0,0, + "valid")]) +]) +])]). +rcbox('#b8cc99','',432,328,560,384,1,2,1,0,10,288430,0,0,0,0,'2',0,[ +]). +rcbox('#3C5A0F','',432,328,560,384,0,2,1,0,10,288431,0,0,0,0,'2',0,[ +]). +text('black',496,337,2,1,1,104,46,288432,18,5,0,0,0,0,2,104,46,0,0,"",0,0,0,0,355,'',[ +minilines(104,46,0,0,1,0,0,[ +mini_line(104,18,5,0,0,0,[ +str_block(0,104,18,5,0,-1,0,0,0,[ +str_seg('black','Helvetica-Bold',1,115200,104,18,5,0,-1,0,0,0,0,0, + "Forwarding")]) +]), +mini_line(67,18,5,0,0,0,[ +str_block(0,67,18,5,0,-1,0,0,0,[ +str_seg('black','Helvetica-Bold',1,115200,67,18,5,0,-1,0,0,0,0,0, + "Control")]) +]) +])]). +poly('black','',2,[ + 964,192,964,280],1,1,1,288438,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +rcbox('#a5b7d6','',768,280,1040,384,1,2,0,0,10,287905,0,0,0,0,'2',0,[ +]). +rcbox('#1F407A','',768,280,1040,384,0,2,1,0,10,286743,0,0,0,0,'2',0,[ +]). +text('black',824,288,1,1,1,51,29,286745,24,5,0,0,0,0,2,51,29,0,0,"",0,0,0,0,312,'',[ +minilines(51,29,0,0,1,0,0,[ +mini_line(51,24,5,0,0,0,[ +str_block(0,51,24,5,0,-2,0,0,0,[ +str_seg('black','Helvetica-Bold',1,138240,51,24,5,0,-2,0,0,0,0,0, + "LSU")]) +]) +])]). +poly('black','',2,[ + 904,280,904,384],0,2,1,288448,0,0,5,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('black','',2,[ + 868,192,868,280],1,1,1,288459,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('black',896,508,1,1,1,10,20,288462,16,4,0,0,0,0,-65534,10,20,0,0,"",0,0,0,0,524,'',[ +minilines(10,20,0,0,1,0,0,[ +mini_line(10,16,4,0,0,0,[ +str_block(0,10,16,4,0,-1,0,0,0,[ +str_seg('black','Helvetica-Bold',1,97920,10,16,4,0,-1,0,0,0,0,0, + "E")]) +]) +])]). +text('black',600,508,1,1,1,10,20,288494,16,4,0,0,0,0,-65534,10,20,0,0,"",0,0,0,0,524,'',[ +minilines(10,20,0,0,1,0,0,[ +mini_line(10,16,4,0,0,0,[ +str_block(0,10,16,4,0,-1,0,0,0,[ +str_seg('black','Helvetica-Bold',1,97920,10,16,4,0,-1,0,0,0,0,0, + "E")]) +]) +])]). +text('black',296,508,1,1,1,10,20,288498,16,4,0,0,0,0,-65534,10,20,0,0,"",0,0,0,0,524,'',[ +minilines(10,20,0,0,1,0,0,[ +mini_line(10,16,4,0,0,0,[ +str_block(0,10,16,4,0,-1,0,0,0,[ +str_seg('black','Helvetica-Bold',1,97920,10,16,4,0,-1,0,0,0,0,0, + "E")]) +]) +])]). +group([ +arc('black','',0,2,1,0,744,552,760,568,760,552,760,584,0,32,32,5760,11520,288353,0,0,10,4,0,0,0,'2','10','4',0,[ +]), +poly('black','',4,[ + 760,552,776,552,776,584,760,584],0,2,1,288354,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]) +], +288516,0,0,[ +]). +poly('black','',3,[ + 744,568,728,568,728,576],0,2,1,288522,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('black','',3,[ + 792,384,792,560,776,560],1,2,1,288531,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('black','',4,[ + 1028,384,1028,520,1028,520,1028,576],0,2,1,288539,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +group([ +arc('black','',0,2,1,0,440,552,456,568,456,552,456,584,0,32,32,5760,11520,288315,0,0,10,4,0,0,0,'2','10','4',0,[ +]), +poly('black','',4,[ + 456,552,472,552,472,584,456,584],0,2,1,288314,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]) +], +288544,0,0,[ +]). +poly('black','',2,[ + 424,576,160,576],1,2,1,288560,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('black','',3,[ + 440,568,424,568,424,576],0,2,1,288561,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +group([ +arc('black','',0,2,1,0,128,552,144,568,144,552,144,584,0,32,32,5760,11520,288574,0,0,10,4,0,0,0,'2','10','4',0,[ +]), +poly('black','',4,[ + 144,552,160,552,160,584,144,584],0,2,1,288573,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]) +], +288572,0,0,[ +]). +poly('black','',3,[ + 184,432,184,560,160,560],1,2,1,288581,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('black','',2,[ + 128,568,40,568],0,2,1,288588,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +text('black',600,476,1,1,1,12,20,288598,16,4,0,0,0,0,-65534,12,20,0,0,"",0,0,0,0,492,'',[ +minilines(12,20,0,0,1,0,0,[ +mini_line(12,16,4,0,0,0,[ +str_block(0,12,16,4,0,-1,0,0,0,[ +str_seg('black','Helvetica-Bold',1,97920,12,16,4,0,-1,0,0,0,0,0, + "C")]) +]) +])]). +oval('#A8322D','',536,492,544,500,0,2,1,288611,0,0,0,0,0,'2',0,[ +]). +group([ +arc('#A8322D','',0,2,1,0,544,472,560,488,560,472,560,504,1,32,32,5760,-11520,288605,0,0,10,4,0,0,0,'2','10','4',0,[ +]), +poly('#A8322D','',4,[ + 560,472,544,472,544,504,560,504],0,2,1,288604,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]) +], +288603,0,0,[ +]). +poly('#A8322D','',3,[ + 512,576,512,480,544,480],0,2,1,288629,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('#3C5A0F','',4,[ + 568,520,528,520,528,496,536,496],0,2,1,288632,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('#A8322D','',2,[ + 576,488,592,488],0,2,1,288639,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +oval('#A8322D','',832,492,840,500,0,2,1,288653,0,0,0,0,0,'2',0,[ +]). +group([ +arc('#A8322D','',0,2,1,0,840,472,856,488,856,472,856,504,1,32,32,5760,-11520,288656,0,0,10,4,0,0,0,'2','10','4',0,[ +]), +poly('#A8322D','',4,[ + 856,472,840,472,840,504,856,504],0,2,1,288655,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]) +], +288654,0,0,[ +]). +poly('#A8322D','',3,[ + 808,576,808,480,840,480],0,2,1,288657,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('#A8322D','',2,[ + 872,488,888,488],0,2,1,288658,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('#3C5A0F','',4,[ + 864,520,824,520,824,496,832,496],0,2,1,288668,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +oval('#A8322D','',232,492,240,500,0,2,1,288675,0,0,0,0,0,'2',0,[ +]). +group([ +arc('#A8322D','',0,2,1,0,240,472,256,488,256,472,256,504,1,32,32,5760,-11520,288678,0,0,10,4,0,0,0,'2','10','4',0,[ +]), +poly('#A8322D','',4,[ + 256,472,240,472,240,504,256,504],0,2,1,288677,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]) +], +288676,0,0,[ +]). +poly('#A8322D','',3,[ + 208,576,208,480,240,480],0,2,1,288679,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('#A8322D','',2,[ + 272,488,288,488],0,2,1,288680,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +poly('#3C5A0F','',4,[ + 256,520,224,520,224,496,232,496],0,2,1,288682,0,0,0,0,0,0,0,'2',0,0, + "0","",[ + 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[ +]). +text('black',296,476,1,1,1,12,20,288685,16,4,0,0,0,0,-65534,12,20,0,0,"",0,0,0,0,492,'',[ +minilines(12,20,0,0,1,0,0,[ +mini_line(12,16,4,0,0,0,[ +str_block(0,12,16,4,0,-1,0,0,0,[ +str_seg('black','Helvetica-Bold',1,97920,12,16,4,0,-1,0,0,0,0,0, + "C")]) +]) +])]). +text('black',896,476,1,1,1,12,20,288687,16,4,0,0,0,0,-65534,12,20,0,0,"",0,0,0,0,492,'',[ +minilines(12,20,0,0,1,0,0,[ +mini_line(12,16,4,0,0,0,[ +str_block(0,12,16,4,0,-1,0,0,0,[ +str_seg('black','Helvetica-Bold',1,97920,12,16,4,0,-1,0,0,0,0,0, + "C")]) +]) +])]). diff --git a/docs/datasheet/preamble/preamble.tex b/docs/datasheet/preamble/preamble.tex index 08b75508..1cfc425c 100644 --- a/docs/datasheet/preamble/preamble.tex +++ b/docs/datasheet/preamble/preamble.tex @@ -55,6 +55,8 @@ \usepackage{enumitem} +\usepackage{tcolorbox} + \usepackage{pdflscape} @@ -115,3 +117,10 @@ \textbf{Operation:} \texttt{#2}% } +\newenvironment{boxnote}% +{% + \begin{tcolorbox}[colback=red!5!white,colframe=red!75!black,title=Note]% +}% +{% + \end{tcolorbox}% +}% diff --git a/exc_controller.sv b/exc_controller.sv index 02954ac2..22f940e0 100644 --- a/exc_controller.sv +++ b/exc_controller.sv @@ -64,7 +64,7 @@ module riscv_exc_controller ); - enum logic [1:0] { IDLE, WAIT_CONTROLLER, IN_ISR } exc_ctrl_cs, exc_ctrl_ns; + enum logic [0:0] { IDLE, WAIT_CONTROLLER } exc_ctrl_cs, exc_ctrl_ns; logic req_int; logic [1:0] pc_mux_int, pc_mux_int_q; @@ -173,7 +173,7 @@ module riscv_exc_controller if (ack_i) begin save_cause_o = 1'b1; - exc_ctrl_ns = IN_ISR; + exc_ctrl_ns = IDLE; end end end @@ -184,16 +184,10 @@ module riscv_exc_controller if (ack_i) begin save_cause_o = 1'b1; - exc_ctrl_ns = IN_ISR; + exc_ctrl_ns = IDLE; end end - IN_ISR: - begin - if (eret_insn_i) - exc_ctrl_ns = IDLE; - end - default: begin exc_ctrl_ns = IDLE; diff --git a/id_stage.sv b/id_stage.sv index 5bd28ffb..588934f7 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -140,7 +140,8 @@ module riscv_id_stage output logic [5:0] exc_cause_o, output logic save_exc_cause_o, - output logic save_pc_id_o, + output logic exc_save_id_o, + output logic exc_restore_id_o, input logic lsu_load_err_i, input logic lsu_store_err_i, @@ -714,7 +715,8 @@ module riscv_id_stage .exc_ack_o ( exc_ack ), .trap_hit_i ( trap_hit ), - .save_pc_id_o ( save_pc_id_o ), + .exc_save_id_o ( exc_save_id_o ), + .exc_restore_id_o ( exc_restore_id_o ), // Debug Unit Signals .dbg_stall_i ( dbg_stall_i ), diff --git a/include/riscv_defines.sv b/include/riscv_defines.sv index dc8f014e..24b92492 100644 --- a/include/riscv_defines.sv +++ b/include/riscv_defines.sv @@ -29,6 +29,7 @@ // no traces for synthesis, they are not synthesizable `ifndef SYNTHESIS `define TRACE_EXECUTION +//`define SIMCHECKER `endif diff --git a/riscv_core.sv b/riscv_core.sv index 743b334d..742845c4 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -190,11 +190,12 @@ module riscv_core // Interrupts logic irq_enable; - logic [31:0] epcr; + logic [31:0] mepc; logic [5:0] exc_cause; logic save_exc_cause; - logic save_pc_id; + logic exc_save_id; + logic exc_restore_id; // Hardware loop controller signals @@ -280,7 +281,7 @@ module riscv_core // control signals .clear_instr_valid_i ( clear_instr_valid ), .pc_set_i ( pc_set ), - .exception_pc_reg_i ( epcr ), // exception return address + .exception_pc_reg_i ( mepc ), // exception return address .pc_mux_i ( pc_mux_id ), // sel for pc multiplexer .exc_pc_mux_i ( exc_pc_mux_id ), .exc_vec_pc_mux_i ( exc_vec_pc_mux_id ), @@ -425,7 +426,8 @@ module riscv_core .irq_enable_i ( irq_enable ), // global interrupt enable .exc_cause_o ( exc_cause ), .save_exc_cause_o ( save_exc_cause ), - .save_pc_id_o ( save_pc_id ), // control signal to save pc + .exc_save_id_o ( exc_save_id ), // control signal to save pc + .exc_restore_id_o ( exc_restore_id ), // control signal to restore pc .lsu_load_err_i ( lsu_load_err ), .lsu_store_err_i ( lsu_store_err ), @@ -611,10 +613,11 @@ module riscv_core // Interrupt related control signals .irq_enable_o ( irq_enable ), - .epcr_o ( epcr ), + .mepc_o ( mepc ), .curr_pc_id_i ( current_pc_id ), // from IF stage - .save_pc_id_i ( save_pc_id ), + .exc_save_i ( exc_save_id ), + .exc_restore_i ( exc_restore_id ), .exc_cause_i ( exc_cause ), .save_exc_cause_i ( save_exc_cause ), @@ -715,47 +718,98 @@ module riscv_core `ifdef TRACE_EXECUTION riscv_tracer riscv_tracer_i ( - .clk ( clk ), - .rst_n ( rst_n ), + .clk ( clk ), + .rst_n ( rst_n ), - .core_id ( core_id_i ), - .cluster_id ( cluster_id_i ), + .fetch_enable ( fetch_enable_i ), + .core_id ( core_id_i ), + .cluster_id ( cluster_id_i ), - .pc ( id_stage_i.current_pc_id_i ), - .instr ( id_stage_i.instr ), - .compressed ( id_stage_i.is_compressed_i ), - .id_valid ( id_stage_i.id_valid_o ), - .is_decoding ( id_stage_i.is_decoding_o ), - .pipe_flush ( id_stage_i.controller_i.pipe_flush_i ), + .pc ( id_stage_i.current_pc_id_i ), + .instr ( id_stage_i.instr ), + .compressed ( id_stage_i.is_compressed_i ), + .id_valid ( id_stage_i.id_valid_o ), + .is_decoding ( id_stage_i.is_decoding_o ), + .pipe_flush ( id_stage_i.controller_i.pipe_flush_i ), - .rs1_value ( id_stage_i.operand_a_fw_id ), - .rs2_value ( id_stage_i.operand_b_fw_id ), - .rs3_value ( id_stage_i.alu_operand_c ), + .rs1_value ( id_stage_i.operand_a_fw_id ), + .rs2_value ( id_stage_i.operand_b_fw_id ), + .rs3_value ( id_stage_i.alu_operand_c ), - .ex_valid ( ex_valid ), - .ex_reg_addr ( regfile_alu_waddr_fw ), - .ex_reg_we ( regfile_alu_we_fw ), - .ex_reg_wdata ( regfile_alu_wdata_fw ), + .ex_valid ( ex_valid ), + .ex_reg_addr ( regfile_alu_waddr_fw ), + .ex_reg_we ( regfile_alu_we_fw ), + .ex_reg_wdata ( regfile_alu_wdata_fw ), - .ex_data_addr ( data_addr_o ), - .ex_data_req ( data_req_o ), - .ex_data_gnt ( data_gnt_i ), - .ex_data_we ( data_we_o ), - .ex_data_wdata ( data_wdata_o ), + .ex_data_addr ( data_addr_o ), + .ex_data_req ( data_req_o ), + .ex_data_gnt ( data_gnt_i ), + .ex_data_we ( data_we_o ), + .ex_data_wdata ( data_wdata_o ), - .wb_valid ( wb_valid ), - .wb_reg_addr ( regfile_waddr_fw_wb_o ), - .wb_reg_we ( regfile_we_wb ), - .wb_reg_wdata ( regfile_wdata ), + .wb_valid ( wb_valid ), + .wb_reg_addr ( regfile_waddr_fw_wb_o ), + .wb_reg_we ( regfile_we_wb ), + .wb_reg_wdata ( regfile_wdata ), - .imm_u_type ( id_stage_i.imm_u_type ), - .imm_uj_type ( id_stage_i.imm_uj_type ), - .imm_i_type ( id_stage_i.imm_i_type ), - .imm_iz_type ( id_stage_i.imm_iz_type[11:0] ), - .imm_z_type ( id_stage_i.imm_z_type ), - .imm_s_type ( id_stage_i.imm_s_type ), - .imm_sb_type ( id_stage_i.imm_sb_type ) + .imm_u_type ( id_stage_i.imm_u_type ), + .imm_uj_type ( id_stage_i.imm_uj_type ), + .imm_i_type ( id_stage_i.imm_i_type ), + .imm_iz_type ( id_stage_i.imm_iz_type[11:0] ), + .imm_z_type ( id_stage_i.imm_z_type ), + .imm_s_type ( id_stage_i.imm_s_type ), + .imm_sb_type ( id_stage_i.imm_sb_type ) + ); +`endif +`ifdef SIMCHECKER + logic is_interrupt; + assign is_interrupt = (pc_mux_id == `PC_EXCEPTION) && (exc_pc_mux_id == `EXC_PC_IRQ); + + riscv_simchecker riscv_simchecker_i + ( + .clk ( clk ), + .rst_n ( rst_n ), + + .fetch_enable ( fetch_enable_i ), + .boot_addr ( boot_addr_i ), + .core_id ( core_id_i ), + .cluster_id ( cluster_id_i ), + + .instr_compressed ( if_stage_i.fetch_rdata[15:0] ), + .pc_set ( pc_set ), + .if_valid ( if_valid ), + + .pc ( id_stage_i.current_pc_id_i ), + .instr ( id_stage_i.instr ), + .is_compressed ( is_compressed_id ), + .id_valid ( id_stage_i.id_valid_o ), + .is_decoding ( id_stage_i.is_decoding_o ), + .is_illegal ( id_stage_i.illegal_insn_dec ), + .is_interrupt ( is_interrupt ), + .irq_no ( exc_vec_pc_mux_id ), + .pipe_flush ( id_stage_i.controller_i.pipe_flush_i ), + + .ex_valid ( ex_valid ), + .ex_reg_addr ( id_stage_i.registers_i.waddr_b_i ), + .ex_reg_we ( id_stage_i.registers_i.we_b_i ), + .ex_reg_wdata ( id_stage_i.registers_i.wdata_b_i ), + + .ex_data_addr ( data_addr_o ), + .ex_data_req ( data_req_o ), + .ex_data_gnt ( data_gnt_i ), + .ex_data_we ( data_we_o ), + .ex_data_wdata ( data_wdata_o ), + + .lsu_misaligned ( data_misaligned ), + + .wb_valid ( wb_valid ), + .wb_reg_addr ( id_stage_i.registers_i.waddr_a_i ), + .wb_reg_we ( id_stage_i.registers_i.we_a_i ), + .wb_reg_wdata ( id_stage_i.registers_i.wdata_a_i ), + + .wb_data_rvalid ( data_rvalid_i ), + .wb_data_rdata ( data_rdata_i ) ); `endif diff --git a/riscv_simchecker.sv b/riscv_simchecker.sv new file mode 100644 index 00000000..73558ed5 --- /dev/null +++ b/riscv_simchecker.sv @@ -0,0 +1,309 @@ +// Copyright 2015 ETH Zurich and University of Bologna. +// Copyright and related rights are licensed under the Solderpad Hardware +// License, Version 0.51 (the “License”); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +// or agreed to in writing, software, hardware and materials distributed under +// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +//////////////////////////////////////////////////////////////////////////////// +// Engineer: Andreas Traber - atraber@iis.ee.ethz.ch // +// // +// Additional contributions by: // +// // +// Design Name: RISC-V Tracer // +// Project Name: RI5CY // +// Language: SystemVerilog // +// // +// Description: Compares the executed instructions with a golden model // +// // +//////////////////////////////////////////////////////////////////////////////// + + +import "DPI-C" function chandle riscv_checker_init(input int boot_addr, input int core_id, input int cluster_id); +import "DPI-C" function int riscv_checker_step(input chandle cpu, input longint simtime, input int cycle, input logic [31:0] pc, input logic [31:0] instr); +import "DPI-C" function void riscv_checker_irq(input chandle cpu, input int irq, input int irq_no); +import "DPI-C" function void riscv_checker_mem_access(input chandle cpu, input int we, input logic [31:0] addr, input logic [31:0] data); +import "DPI-C" function void riscv_checker_reg_access(input chandle cpu, input logic [31:0] addr, input logic [31:0] data); + +module riscv_simchecker +( + // Clock and Reset + input logic clk, + input logic rst_n, + + input logic fetch_enable, + input logic [31:0] boot_addr, + input logic [4:0] core_id, + input logic [4:0] cluster_id, + + input logic [15:0] instr_compressed, + input logic if_valid, + input logic pc_set, + + input logic [31:0] pc, + input logic [31:0] instr, + input logic is_compressed, + input logic id_valid, + input logic is_decoding, + input logic is_illegal, + input logic is_interrupt, + input logic [4:0] irq_no, + input logic pipe_flush, + + input logic ex_valid, + input logic [ 4:0] ex_reg_addr, + input logic ex_reg_we, + input logic [31:0] ex_reg_wdata, + + input logic ex_data_req, + input logic ex_data_gnt, + input logic ex_data_we, + input logic [31:0] ex_data_addr, + input logic [31:0] ex_data_wdata, + + input logic lsu_misaligned, + + input logic wb_valid, + input logic [ 4:0] wb_reg_addr, + input logic wb_reg_we, + input logic [31:0] wb_reg_wdata, + + input logic wb_data_rvalid, + input logic [31:0] wb_data_rdata +); + + // DPI stuff + chandle dpi_simdata; + + // SV-only stuff + typedef struct { + logic [ 4:0] addr; + logic [31:0] value; + } reg_t; + + typedef struct { + logic [31:0] addr; + logic we; + logic [ 3:0] be; + logic [31:0] wdata; + logic [31:0] rdata; + } mem_acc_t; + + class instr_trace_t; + time simtime; + int cycles; + logic [31:0] pc; + logic [31:0] instr; + logic irq; + logic [ 4:0] irq_no; + reg_t regs_write[$]; + mem_acc_t mem_access[$]; + + function new (); + irq = 1'b0; + regs_write = {}; + mem_access = {}; + endfunction + endclass + + mailbox rdata_stack = new (4); + integer rdata_writes = 0; + + integer cycles; + + logic [15:0] instr_compressed_id; + logic is_irq_if, is_irq_id; + logic [ 4:0] irq_no_id, irq_no_if; + + mailbox instr_ex = new (2); + mailbox instr_wb = new (2); + + // simchecker initialization + initial + begin + wait(rst_n == 1'b1); + wait(fetch_enable == 1'b1); + + dpi_simdata = riscv_checker_init(boot_addr, core_id, cluster_id); + end + + // virtual ID/EX pipeline + initial + begin + instr_trace_t trace; + mem_acc_t mem_acc; + reg_t reg_write; + + while(1) begin + instr_ex.get(trace); + + // wait until we are going to the next stage + do begin + @(negedge clk); + + reg_write.addr = ex_reg_addr; + reg_write.value = ex_reg_wdata; + + if (ex_reg_we) + trace.regs_write.push_back(reg_write); + + // look for data accesses and log them + if (ex_data_req && ex_data_gnt) begin + mem_acc.addr = ex_data_addr; + mem_acc.we = ex_data_we; + + if (mem_acc.we) + mem_acc.wdata = ex_data_wdata; + else + mem_acc.wdata = 'x; + + trace.mem_access.push_back(mem_acc); + end + end while (!ex_valid || lsu_misaligned); + + instr_wb.put(trace); + end + end + + // virtual EX/WB pipeline + initial + begin + instr_trace_t trace; + reg_t reg_write; + logic [31:0] tmp_discard; + + while(1) begin + instr_wb.get(trace); + + // wait until we are going to the next stage + do begin + @(negedge clk); + #1; + + // pop rdata from stack when there were pending writes + while(rdata_stack.num() > 0 && rdata_writes > 0) begin + rdata_writes--; + rdata_stack.get(tmp_discard); + end + + end while (!wb_valid); + + reg_write.addr = wb_reg_addr; + reg_write.value = wb_reg_wdata; + + if (wb_reg_we) + trace.regs_write.push_back(reg_write); + + // keep care of rdata + foreach(trace.mem_access[i]) begin + if (trace.mem_access[i].we) begin + // for writes we don't need to wait for the rdata, so if it has + // not appeared yet, we count it and remove it later from out + // stack + rdata_writes++; + + end else begin + if (rdata_stack.num() == 0) + $warning("rdata stack is empty, but we are waiting for a read"); + + rdata_stack.get(trace.mem_access[i].rdata); + end + end + + // instruction is ready now, all data is inserted + foreach(trace.mem_access[i]) begin + if (trace.mem_access[i].we) + riscv_checker_mem_access(dpi_simdata, trace.mem_access[i].we, trace.mem_access[i].addr, trace.mem_access[i].wdata); + else + riscv_checker_mem_access(dpi_simdata, trace.mem_access[i].we, trace.mem_access[i].addr, trace.mem_access[i].rdata); + end + + foreach(trace.regs_write[i]) begin + riscv_checker_reg_access(dpi_simdata, trace.regs_write[i].addr, trace.regs_write[i].value); + end + + riscv_checker_irq(dpi_simdata, trace.irq, trace.irq_no); + + if (riscv_checker_step(dpi_simdata, trace.simtime, trace.cycles, trace.pc, trace.instr)) + $display("%t: Cluster %d, Core %d: Mismatch between simulator and RTL detected", trace.simtime, cluster_id, core_id); + end + end + + // cycle counter + always_ff @(posedge clk, negedge rst_n) + begin + if (rst_n == 1'b0) + cycles = 0; + else + cycles = cycles + 1; + end + + // create rdata stack + initial + begin + while(1) begin + @(negedge clk); + + if (wb_data_rvalid) begin + rdata_stack.put(wb_data_rdata); + end + end + end + + always_ff @(posedge clk) + begin + if (pc_set) begin + is_irq_if <= is_interrupt; + irq_no_if <= irq_no; + end else if (if_valid) begin + is_irq_if <= 1'b0; + end + end + + always_ff @(posedge clk) + begin + if (if_valid) begin + instr_compressed_id <= instr_compressed; + is_irq_id <= is_irq_if; + irq_no_id <= irq_no_if; + end + end + + // log execution + initial + begin + instr_trace_t trace; + + while(1) begin + @(negedge clk); + + // - special case for WFI because we don't wait for unstalling there + // - special case for illegal instructions, since they will not go through + // the pipe + if ((id_valid && is_decoding) || pipe_flush || (is_decoding && is_illegal)) + begin + trace = new (); + + trace.simtime = $time; + trace.cycles = cycles; + trace.pc = pc; + + if (is_compressed) + trace.instr = {instr_compressed_id, instr_compressed_id}; + else + trace.instr = instr; + + if (is_irq_id) begin + trace.irq = 1'b1; + trace.irq_no = irq_no_id; + end + + instr_ex.put(trace); + end + end + end + +endmodule diff --git a/riscv_tracer.sv b/riscv_tracer.sv index 6ff81ba6..930aed2b 100644 --- a/riscv_tracer.sv +++ b/riscv_tracer.sv @@ -30,6 +30,7 @@ module riscv_tracer input logic clk, input logic rst_n, + input logic fetch_enable, input logic [4:0] core_id, input logic [4:0] cluster_id, @@ -67,7 +68,6 @@ module riscv_tracer input logic [31:0] imm_z_type, input logic [31:0] imm_s_type, input logic [31:0] imm_sb_type - ); integer f; @@ -187,7 +187,7 @@ module riscv_tracer function void printUInstr(input string mnemonic); begin regs_write.push_back({rd, 'x}); - str = $sformatf("%-16s x%0d, 0x%0h000", mnemonic, rd, imm_u_type[31:12]); + str = $sformatf("%-16s x%0d, 0x%0h", mnemonic, rd, {imm_u_type[31:12], 12'h000}); end endfunction // printUInstr @@ -375,11 +375,13 @@ module riscv_tracer // open/close output file for writing initial begin - #1 // delay needed for valid core_id and cluster_id + wait(rst_n == 1'b1); + wait(fetch_enable == 1'b1); $sformat(fn, "trace_core_%h_%h.log", cluster_id, core_id); $display("[TRACER] Output filename is: %s", fn); f = $fopen(fn, "w"); - $fwrite(f, "%20s\t%6s\t%10s\t%10s\t \t%s\n", "Time", "Cycles", "PC", "Instr", "Mnemonic"); + $fwrite(f, " Time Cycles PC Instr Mnemonic\n"); + end final @@ -403,7 +405,7 @@ module riscv_tracer // wait until we are going to the next stage do begin - @(posedge clk); + @(negedge clk); // replace register written back foreach(trace.regs_write[i]) @@ -438,7 +440,7 @@ module riscv_tracer // wait until we are going to the next stage do begin - @(posedge clk); + @(negedge clk); // replace register written back foreach(trace.regs_write[i]) @@ -451,7 +453,7 @@ module riscv_tracer end // log execution - always @(posedge clk) + always @(negedge clk) begin instr_trace_t trace; @@ -502,10 +504,10 @@ module riscv_tracer `INSTR_SRA: trace.printRInstr("sra"); `INSTR_OR: trace.printRInstr("or"); `INSTR_AND: trace.printRInstr("and"); - `INSTR_EXTHS: trace.printRInstr("exths"); - `INSTR_EXTHZ: trace.printRInstr("exthz"); - `INSTR_EXTBS: trace.printRInstr("extbs"); - `INSTR_EXTBZ: trace.printRInstr("extbz"); + `INSTR_EXTHS: trace.printRInstr("p.exths"); + `INSTR_EXTHZ: trace.printRInstr("p.exthz"); + `INSTR_EXTBS: trace.printRInstr("p.extbs"); + `INSTR_EXTBZ: trace.printRInstr("p.extbz"); `INSTR_PAVG: trace.printRInstr("p.avg"); `INSTR_PAVGU: trace.printRInstr("p.avgu"); `INSTR_PSLET: trace.printRInstr("p.slet"); @@ -545,7 +547,4 @@ module riscv_tracer end end // always @ (posedge clk) - - - endmodule