Git commit 9c0786f4380bf78dd71a254ae7814e48266653ef by Christoph Cullmann. Committed on 09/09/2014 at 19:21. Pushed by cullmann into branch 'master'. new hl test infrastructure, using the HTML reporter M +1 -0 autotests/CMakeLists.txt A +1 -0 autotests/input/syntax/.gitignore A +32 -0 autotests/input/syntax/dockerfile/results/Dockerfile.referen= ce.html A +576 -0 autotests/input/syntax/verilog/results/or1200_dc_fsm.v.refer= ence.html A +1816 -0 autotests/input/syntax/verilog/results/or1200_du.v.reference= .html A +257 -0 autotests/input/syntax/vhdl/results/light52_muldiv.vhdl.refe= rence.html A +196 -0 autotests/input/syntax/vhdl/results/light52_tb.vhdl.referenc= e.html A +129 -0 autotests/src/katesyntaxtest.cpp [License: LGPL (v2+)] A +38 -0 autotests/src/katesyntaxtest.h [License: LGPL (v2+)] M +3 -11 src/export/exporter.cpp M +1 -1 src/export/exporter.h M +10 -2 src/view/kateview.cpp M +2 -0 src/view/kateview.h http://commits.kde.org/ktexteditor/9c0786f4380bf78dd71a254ae7814e48266653ef diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 90cd643..e16715f 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -123,6 +123,7 @@ ktexteditor_unit_test(commands_test src/script_test_bas= e.cpp src/testutils.cpp) ktexteditor_unit_test(scripting_test src/script_test_base.cpp src/testutil= s.cpp) ktexteditor_unit_test(bug313759 src/testutils.cpp) ktexteditor_unit_test(bug317111 src/testutils.cpp) +ktexteditor_unit_test(katesyntaxtest) = if (BUILD_VIMODE) add_subdirectory(src/vimode) diff --git a/autotests/input/syntax/.gitignore b/autotests/input/syntax/.gi= tignore new file mode 100644 index 0000000..704dc35 --- /dev/null +++ b/autotests/input/syntax/.gitignore @@ -0,0 +1 @@ +*.current.html diff --git a/autotests/input/syntax/dockerfile/results/Dockerfile.reference= .html b/autotests/input/syntax/dockerfile/results/Dockerfile.reference.html new file mode 100644 index 0000000..7349a7b --- /dev/null +++ b/autotests/input/syntax/dockerfile/results/Dockerfile.reference.html @@ -0,0 +1,32 @@ + + + +
+ + ++# LGPLv2+ example file + +# This is a comment +FROM ubuntu:14.04 +MAINTAINER James Turnbull <james@example.com> # comment +ENV REFRESHED_AT 2014-06-01 + +RUN apt-get -yqq update +RUN apt-get install -yqq software-properties-common python-software= -properties +RUN add-apt-repository ppa:chris-lea/redis-server +RUN apt-get -yqq update +RUN apt-get -yqq install redis-server redis-tools +RUN apt-get -yqq update # comment + +VOLUME [ "/var/lib/redis"<= /span>, "/var/log/redis/" ] + +EXPOSE 6379 + +CMD [] ++ + diff --git a/autotests/input/syntax/verilog/results/or1200_dc_fsm.v.referen= ce.html b/autotests/input/syntax/verilog/results/or1200_dc_fsm.v.reference.= html new file mode 100644 index 0000000..664bd2d --- /dev/null +++ b/autotests/input/syntax/verilog/results/or1200_dc_fsm.v.reference.html @@ -0,0 +1,576 @@ + + + + + + +
+///////////////////////////////////////////= /////////////////////////// +//// = //// +//// OR1200's DC FSM = //// +//// = //// +//// This file is part of the OpenRISC 120= 0 project //// +//// http://opencores.org/project,or1k = //// +//// = //// +//// Description = //// +//// Data cache state machine = //// +//// = //// +//// To Do: = //// +//// - Test error during line read or wri= te //// +//// = //// +//// Author(s): = //// +//// - Damjan Lampret, lampret@opencor= es.org //// +//// - Julius Baxter, julius@opencores= .org //// +//// = //// +///////////////////////////////////////////= /////////////////////////// +//// = //// +//// Copyright (C) 2000, 2010 Authors and O= PENCORES.ORG //// +//// = //// +//// This source file may be used and distr= ibuted without //// +//// restriction provided that this copyrig= ht statement is not //// +//// removed from the file and that any der= ivative work contains //// +//// the original copyright notice and the = associated disclaimer. //// +//// = //// +//// This source file is free software; you= can redistribute it //// +//// and/or modify it under the terms of th= e GNU Lesser General //// +//// Public License as published by the Fre= e Software Foundation; //// +//// either version 2.1 of the License, or = (at your option) any //// +//// later version. = //// +//// = //// +//// This source is distributed in the hope= that it will be //// +//// useful, but WITHOUT ANY WARRANTY; with= out even the implied //// +//// warranty of MERCHANTABILITY or FITNESS= FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General P= ublic License for more //// +//// details. = //// +//// = //// +//// You should have received a copy of the= GNU Lesser General //// +//// Public License along with this source;= if not, download it //// +//// from http://www.opencores.org/lgpl.sht= ml //// +//// = //// +///////////////////////////////////////////= /////////////////////////// +// +// $Log: or1200_dc_fsm.v,v $ +// Revision 2.0 2010/06/30 11:00:00 ORSoC= +// Minor update: +// Bugs fixed. +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on +`include "or1200_defines.v" + +`define OR1200_DCFSM_IDLE 3'd0 +`define OR1200_DCFSM_CLOADSTORE 3'd1 +`define OR1200_DCFSM_LOOP2 3'd2 +`define OR1200_DCFSM_LOOP3 3'd3 +`define OR1200_DCFSM_LOOP4 3'd4 +`define OR1200_DCFSM_FLUSH5 3'd5 +`define OR1200_DCFSM_INV6 3'd6 +`define OR1200_DCFSM_WAITSPRCS7 3'd7 + + + +// +// Data cache FSM for cache line of 16 byte= s (4x singleword) +// + +module or1200_dc_fsm + ( + // Clock and reset + clk, rst, + = + // Internal i/f to top level DC + dc_en, dcqmem_cycstb_i, dcqmem_ci_i, dcqmem_we_i, dcqmem_sel_i, + tagcomp_miss, biudata_valid, biudata_error, lsu_addr, + dcram_we, biu_read, biu_write, biu_do_sel, dcram_di_sel, first_hit_ack, = + first_miss_ack, first_miss_err, burst, tag_we, tag_valid, dc_addr, = + dc_no_writethrough, tag_dirty, dirty, tag, tag_v, dc_block_flush, = + dc_block_writeback, spr_dat_i, mtspr_dc_done, spr_cswe + ); + + // + // I/O + // + input clk; + input rst; + input dc_en; + input dcqmem_cycstb_i; + input dcqmem_ci_i; + input dcqmem_we_i; + input [3:0] dcqmem_sel_i; + input tagcomp_miss; + input biudata_valid; + input biudata_error; + input [31:0] lsu_addr; + output [3:0] dcram_we; + output biu_read; + output biu_write; + output dcram_di_sel; + output biu_do_sel; + output first_hit_ack; + output first_miss_ack; + output first_miss_err; + output burst; + output tag_we; + output tag_valid; + output [31:0] dc_addr; + input dc_no_writethrough; + output tag_dirty; + input dirty; + input [`OR1200_DCTAG_W-2:0] tag; + input tag_v; = + input dc_block_flush; + input dc_block_writeback; + input [31:0] spr_dat_i; + output mtspr_dc_done; + input spr_cswe; + = + = + // + // Internal wires and regs + // + reg [31:0] addr_r; + reg [2:0] state; + reg [`OR1200_DCLS-1:0] cnt; + reg hitmiss_eval; + reg store; + reg load; + reg cache_inhibit; + reg cache_miss; + reg cache_dirty_needs_writeb= ack; + reg = did_early_load_ack; + reg cache_spr_block_flush; + reg cache_spr_block_writebac= k; + reg cache_wb; = + wire load_hit_ack; + wire load_miss_ack; + wire load_inhibit_ack; = + wire store_hit_ack; + wire store_hit_writethrough_a= ck; = + wire store_miss_writethrough_= ack; = + wire store_inhibit_ack; + wire store_miss_ack; + wire dcram_we_after_line_load; + wire dcram_we_during_line_loa= d; + wire tagram_we_end_of_loadsto= re_loop; + wire tagram_dirty_bit_set; = + wire writethrough; + wire cache_inhibit_with_eval; + wire [(`OR1200_DCLS-1)-2:0] ne= xt_addr_word; + + // + // Cache inhibit + // + = + // Indicates whether cache is inhibited,= during hitmiss_eval and after + assign cache_inhibit_with_eval =3D (hitmiss_eval & dcqmem_ci= _i) | + (!hitmiss_eval & cache_inhibit); + = + // + // Generate of DCRAM write enables + // + + // WE when non-writethrough, and had to = wait for a line to load. + assign dcram_we_after_line_load =3D (state =3D=3D `OR1200_DCFSM_LOOP3) & + dcqmem_we_i & !cache_dirty_needs_writeback & + !did_early_load_ack; + + // WE when receiving the data cache line= + assign dcram_we_during_line_load =3D (state =3D=3D `OR1200_DCFSM_LOOP2) & load & = + biudata_valid; = + = + assign dcram_we =3D(// Write when= hit - make sure it is only when hit - could + // maybe be doing write through and = don't want to corrupt + // cache lines corresponding to the = writethrough addr_r. + ({4{store_hit_ack | store_hit= _writethrough_ack}} | + // Write after load of line + {4{dcram_we_after_line_load}}= ) & = + dcqmem_sel_i ) | + // Write during load + {4{dcram_we_during_line_load}}; + + // + // Tag RAM signals + // + = + // WE to tag RAM when we finish loading = a line. + assign tagram_we_end_of_loadstore_loop =3D ((state=3D=3D`OR1200_DCFSM_LOOP2) & = + biudata_valid & !(|cnt)); + = +`ifndef OR1200_DC_WRITETHROUGH + // No writethrough, so mark a line dirty= whenever we write to it + assign tagram_dirty_bit_set =3D store_hit_ack | store_miss_ack; + + // Generate done signal for MTSPR instru= ctions that may block execution + assign mtspr_dc_done =3D // Eithe= r DC disabled or we're not selected, or + !dc_en | !spr_cswe | + // Requested address not valid or writ= eback and !dirty + ((state=3D=3D`OR1200_DCFSM_FLUSH5) & = + (!tag_v | (cache_spr_block_writeback & !dirty))) | + // Writeback or flush is finished + ((state=3D=3D`OR1200_DCFSM_LOOP3) & = + (cache_spr_block_flush | cache_spr_block_writeback))| + // Invalidate of clean line finished= span> + ((state=3D=3D`OR1200_DCFSM_INV6= ) & cache_spr_block_flush); + = + = +`else + `ifdef OR1200_DC_NOSTACKWRITETHROUG= H = + // For dirty bit setting when having wri= tethrough but not for stack + assign tagram_dirty_bit_set =3D store_hit_ack | store_miss_ack; + `else + // Lines will never be dirty if always w= ritethrough + assign tagram_dirty_bit_set =3D 0= ; + `endif + = + assign mtspr_dc_done =3D 1'b1; + = +`endif + + assign tag_dirty =3D tagram_dirty_bit_set; + = + // WE to tag RAM + assign tag_we =3D tagram_we_end_of_loadstore_loop | = + tagram_dirty_bit_set | (state =3D=3D `OR1200_DCFSM_INV6); + = + + // Valid bit + // Set valid when end of line load, or m= arking dirty (is still valid) + assign tag_valid =3D ( tagram_we_end_of_loadstore_loop & = + (load | (store & cache_spr_block_writeback)) ) | + tagram_dirty_bit_set; + + + = + // + // BIU read and write + // + + assign biu_read =3D // Bus read r= equest when: + // 1) Have a miss and not dirty or a= load with inhibit + ((state =3D=3D `OR1200_DCFSM_CLOADST= ORE) & + (((hitmiss_eval & tagcomp_miss & !dirty & = + !(store & writethrough)) | = + (load & cache_inhibit_with_eval)) & dcqmem_cycstb_i)) | + // 2) In the loop and loading + ((state =3D=3D `OR1200_DCFSM_LOOP2= span>) & load); + = + + assign biu_write =3D // Bus write= request when: + // 1) Have a miss and dirty or stor= e with inhibit + ((state =3D=3D `OR1200_DCFSM_CLOADS= TORE) & = + (((hitmiss_eval & tagcomp_miss & dirty) | = + (store & writethrough)) | = + (store & cache_inhibit_with_eval)) & dcqmem_cycstb_i) | + // 2) In the loop and storing + ((state =3D=3D `OR1200_DCFSM_LOOP2<= /span>) & store); + = + // + // Select for data to actual cache RAM (= from LSU or BIU) + // + // Data to DCRAM - from external bus whe= n loading (from IU when store) + assign dcram_di_sel =3D load; + // Data to external bus - always from IU= except in case of bursting back + // the line to me= mory. (1 selects DCRAM) + assign biu_do_sel =3D (state =3D=3D `OR1200_DCFSM_LOOP2) & store; + + // 3-bit wire for calculating next word = of burst write, depending on + // line size of data cache. + assign next_addr_word =3D addr_r[`OR1200_DCLS-1:2] + 1; + = + // Address to cache RAM (tag address als= o derived from this) + assign dc_addr =3D + // First check if we've got a block fl= ush or WB op + ((dc_block_flush & !cache_spr_block_flush) | = + (dc_block_writeback & !cache_spr_block_writeback)) ? = + spr_dat_i : + (state=3D=3D`OR1200_DCFSM_FLUSH5) ? addr_r: + // If no SPR action, then always put = out address from LSU + (state=3D=3D`OR1200_DCFSM_IDLE= | hitmiss_eval) ? lsu_addr : + // Next, if in writeback loop, when A= CKed must immediately + // output next word address (the RAM = address takes a cycle + // to increment, but it's needed imme= diately for burst) + // otherwise, output our registered a= ddress. + (state=3D=3D`OR1200_DCFSM_LOOP2 & biudata_valid & store ) ? = + {addr_r[31:`OR1200_DCLS], next_addr_word, 2'b00} : addr_r; + = +`ifdef OR1200_DC_WRITETHROUGH + `ifdef OR1200_DC_NOSTACKWRITETHROUG= H = + assign writethrough =3D !dc_no_writethrough; + `else + assign writethrough =3D 1; + `endif +`else + assign writethrough =3D 0; +`endif + = + // + // ACK generation for LSU + // + = + // ACK for when it's a cache hit + assign first_hit_ack =3D load_hit_ack | store_hit_ack | = + store_hit_writethrough_ack | = + store_miss_writethrough_ack | + store_inhibit_ack | store_miss_ack ; + + // ACK for when it's a cache miss - load= only, is used in MUX for data back + // LSU = straight off external data bus. In + // this= was is also used for cache inhibit + // load= s. + // first_hit_ack takes precedence over f= irst_miss_ack + assign first_miss_ack =3D ~first_hit_ack & (load_miss_ack | = load_inhibit_ack); + = + // ACK cache hit on load + assign load_hit_ack =3D (state =3D=3D `OR1200_DCFSM_CLOADSTORE) & = + hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i & load; + = + // ACK cache hit on store, no writethrou= gh + assign store_hit_ack =3D (state =3D=3D `OR1200_DCFSM_CLOADSTORE) & = + hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i & + store & !writethrough; + = + // ACK cache hit on store with writethro= ugh + assign store_hit_writethrough_ack =3D (state =3D=3D `OR1200_DCFSM_CLOADSTORE) & = + !cache_miss & !cache_inhibit & + store & writethrough & biudata_valid; + = + // ACK cache miss on store with writethr= ough + assign store_miss_writethrough_ack =3D (state =3D=3D `OR1200_DCFSM_CLOADSTORE) & = + cache_miss & !cache_inhibit & + store & writethrough & biudata_valid; + = + // ACK store when cacheinhibit + assign store_inhibit_ack =3D (state =3D=3D `OR1200_DCFSM_CLOADSTORE) & + store & cache_inhibit & biudata_valid; + = + = + // Get the _early_ ack on first ACK back= from wishbone during load only + // Condition is that we're in the loop -= that it's the first ack we get (can + // tell from value of cnt), and we're lo= ading a line to read from it (not + // loading to write to it, in the case o= f a write without writethrough.) + assign load_miss_ack =3D ((state=3D=3D `OR1200_DCFSM_LOOP2) & load & + (cnt=3D=3D((1 << `OR1200_DCLS) - 4)) & biudata_valid & = + !(dcqmem_we_i & !writethrough)); + = + assign load_inhibit_ack =3D (state =3D=3D `OR1200_DCFSM_CLOADSTORE) & + load & cache_inhibit & biudata_valid; = + = + // This will be case of write through di= sabled, and had to load a line. + assign store_miss_ack =3D dcram_we_after_line_load; + = + assign first_miss_err =3D biudata_error & dcqmem_cycstb_i; + + // Signal burst when in the load/store l= oop. We will always try to burst. + assign burst =3D (state =3D=3D `O= R1200_DCFSM_LOOP2); + + // + // Main DC FSM + // + always @(posedge clk or `OR1200_RST_EVENT rst) begin<= /b> + if (rst =3D=3D `OR1200_RST_VAL= UE) begin + state <=3D `OR1200_DCFSM_IDLE; + addr_r <=3D 32'd0; + hitmiss_eval <=3D 1'b0; + store <=3D 1'b0; + load <=3D 1'b0; + cnt <=3D `OR1200_DCLS'd0; + cache_miss <=3D 1'b0; + cache_dirty_needs_writeback <=3D 1'b0<= /span>; + cache_inhibit <=3D 1'b0; + did_early_load_ack <=3D 1'b0; + cache_spr_block_flush <=3D 1'b0; + cache_spr_block_writeback <=3D 1'b0; + end + else + case (state) // synopsys parallel_c= ase + = + `OR1200_DCFSM_IDLE : be= gin + if (dc_en & (dc_block_flush | dc_block_writeback)) + begin + cache_spr_block_flush <=3D dc_block_flush; + cache_spr_block_writeback <=3D dc_block_writeback; + hitmiss_eval <=3D 1'b1; + state <=3D `OR1200_DCFSM_FLUSH5; + addr_r <=3D spr_dat_i; + end + else if (dc_en & dcqmem_cycstb_i) + begin + state <=3D `OR1200_DCFSM_CLOADSTORE<= /span>; + hitmiss_eval <=3D 1'b1; + store <=3D dcqmem_we_i; + load <=3D !dcqmem_we_i; + end + = + = + end // case: `OR1200_DCFSM= _IDLE + = + `OR1200_DCFSM_CLOADSTORE: = begin + hitmiss_eval <=3D 1'b0; + if (hitmiss_eval) begin + cache_inhibit <=3D dcqmem_ci_i; // Check for cache inhibit here + cache_miss <=3D tagcomp_miss; + cache_dirty_needs_writeback <=3D dirty; + addr_r <=3D lsu_addr; + end + + // Evaluate any cache line load/store= s in first cycle: + // + if (hitmiss_eval & tagcomp_miss & !(store & write= through) & + !dcqmem_ci_i) + begin + // Miss - first either: + // 1) write back dirty line + if (dirty) begin + // Address for writeback + addr_r <=3D {tag, lsu_addr[`OR12= 00_DCINDXH:2],2'd0}; + load <=3D 1'b0; + store <=3D 1'b1; +`ifdef OR1200_VERBOSE + $display("%t: dcache miss and dirty", $time); +`endif + end + // 2) load requested line + else begin + addr_r <=3D lsu_addr; + load <=3D 1'b1; + store <=3D 1'b0; + end // else: !if(dirty) + state <=3D `OR1200_DCFSM_LOOP2; = + // Set the counter for the burst access= es + cnt <=3D ((1 << `OR1200_DCLS) - 4); + end + else if (// Stro= be goes low + !dcqmem_cycstb_i | + // Cycle finishes + (!hitmiss_eval & (biudata_valid | biudata_error)) | + // Cache hit in first cycle.... + (hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i & + // .. and you're not doing a writet= hrough store.. + !(store & writethrough))) begin + state <=3D `OR1200_DCFS= M_IDLE; + load <=3D 1'b0; + store <=3D 1'b0; + cache_inhibit <=3D 1'b0; + cache_dirty_needs_writeback <=3D 1'b0<= /span>; + end = + end // case: `OR1200_DCFSM= _CLOADSTORE + = + `OR1200_DCFSM_LOOP2 : b= egin // loop/abort + if (!dc_en| biudata_error) begin + state <=3D `OR1200_DCFS= M_IDLE; + load <=3D 1'b0; + store <=3D 1'b0; + cnt <=3D `OR1200_DCLS'd0; + end + if (biudata_valid & (|cnt)) begin + cnt <=3D cnt - 4; + addr_r[`OR1200_DCLS-= 1:2] <=3D addr_r[`OR1200_DCLS-+ + diff --git a/autotests/input/syntax/verilog/results/or1200_du.v.reference.h= tml b/autotests/input/syntax/verilog/results/or1200_du.v.reference.html new file mode 100644 index 0000000..3dc2f5c --- /dev/null +++ b/autotests/input/syntax/verilog/results/or1200_du.v.reference.html @@ -0,0 +1,1816 @@ + + + + + + +1:2] + 1; + end + else if (biudata_valid & !(|cnt)) begin + state <=3D `OR1200_DCFSM_LOOP3; + addr_r <=3D lsu_addr; + load <=3D 1'b0; + store <=3D 1'b0; + end + + // Track if we did an early ack durin= g a load + if (load_miss_ack) + did_early_load_ack <=3D 1'b1; + = + + end // case: `OR1200_DCFSM= _LOOP2 + = + `OR1200_DCFSM_LOOP3: begin= // figure out next step + if (cache_dirty_needs_writeback) begin + // Just did store of the dirty line so no= w load new one + load <=3D 1'b1; + // Set the counter for the burst accesses= + cnt <=3D ((1 << `OR1200_DCLS) - 4); + // Address of line to be loaded + addr_r <=3D lsu_addr; + cache_dirty_needs_writeback <=3D 1'b0<= /span>; + state <=3D `OR1200_DCFSM_LOOP2; + end // if (cache_dirty_needs_w= riteback) + else if (cache_spr_block_flush | cache_spr_block_write= back) begin + // Just wrote back the line to memory, we= 're finished. + cache_spr_block_flush <=3D 1'b0; + cache_spr_block_writeback <=3D 1'b0; + state <=3D `OR1200_DCFSM_WAITSPRCS7; + end + else begin + // Just loaded a new line, finish up + did_early_load_ack <=3D 1'b0; + state <=3D `OR1200_DCFSM_LOOP4; + end + end // case: `OR1200_DCFSM_LOOP3<= /span> + + `OR1200_DCFSM_LOOP4: begin + state <=3D `OR1200_DCFSM_IDLE; + end + + `OR1200_DCFSM_FLUSH5: begin + hitmiss_eval <=3D 1'b0; + if (hitmiss_eval & !tag_v) + begin + // Not even cached, just ignore + cache_spr_block_flush <=3D 1'b0; + cache_spr_block_writeback <=3D 1'b0<= /span>; + state <=3D `OR1200_DCFSM_WAITSPRCS7= ; + end + else if (hitmiss_eval & tag_v) + begin + // Tag is valid - what do we do? + if ((cache_spr_block_flush | cache_spr_block_writeback) & = + dirty) begin + // Need to writeback + // Address for writeback (spr_dat_i = has already changed so + // use line number from addr_r) + addr_r <=3D {tag, addr_r[`OR1200= _DCINDXH:2],2'd0}; + load <=3D 1'b0; + store <=3D 1'b1; +`ifdef OR1200_VERBOSE + $display("%t: block flush: dirty block", $time); +`endif + state <=3D `OR1200_DCFSM_LOOP2; = + // Set the counter for the burst acc= esses + cnt <=3D ((1 <<`OR1200_DCLS ) - 4); + end + else if (cache_spr_block_flush & !dirty) + begin + // Line not dirty, just need to in= validate + state <=3D `OR1200_DCFSM_INV6<= /span>; + end // else: !if(dirty) + else if (cache_spr_block_writeback & !dirty) + begin + // Nothing to do - line is valid b= ut not dirty + cache_spr_block_writeback <=3D = 1'b0; + state <=3D `OR1200_DCFSM_WAITS= PRCS7; + end + end // if (hitmiss_eval & tag= _v) + end + `OR1200_DCFSM_INV6: begin + cache_spr_block_flush <=3D 1'b0; + // Wait until SPR CS goes low before = going back to idle + if (!spr_cswe) + state <=3D `OR1200_DCFSM_IDLE= span>; + end + `OR1200_DCFSM_WAITSPRCS7: begi= n + // Wait until SPR CS goes low before = going back to idle + if (!spr_cswe) + state <=3D `OR1200_DCFSM_IDLE= span>; + end + + endcase // case (state) + = + end // always @ (posedge clk or `= OR1200_RST_EVENT rst) + = + +endmodule +
+///////////////////////////////////////////= /////////////////////////// +//// = //// +//// OR1200's Debug Unit = //// +//// = //// +//// This file is part of the OpenRISC 120= 0 project //// +//// http://www.opencores.org/project,or1k= //// +//// = //// +//// Description = //// +//// Basic OR1200 debug unit. = //// +//// = //// +//// To Do: = //// +//// - make it smaller and faster = //// +//// = //// +//// Author(s): = //// +//// - Damjan Lampret, lampret@opencor= es.org //// +//// = //// +///////////////////////////////////////////= /////////////////////////// +//// = //// +//// Copyright (C) 2000 Authors and OPENCOR= ES.ORG //// +//// = //// +//// This source file may be used and distr= ibuted without //// +//// restriction provided that this copyrig= ht statement is not //// +//// removed from the file and that any der= ivative work contains //// +//// the original copyright notice and the = associated disclaimer. //// +//// = //// +//// This source file is free software; you= can redistribute it //// +//// and/or modify it under the terms of th= e GNU Lesser General //// +//// Public License as published by the Fre= e Software Foundation; //// +//// either version 2.1 of the License, or = (at your option) any //// +//// later version. = //// +//// = //// +//// This source is distributed in the hope= that it will be //// +//// useful, but WITHOUT ANY WARRANTY; with= out even the implied //// +//// warranty of MERCHANTABILITY or FITNESS= FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General P= ublic License for more //// +//// details. = //// +//// = //// +//// You should have received a copy of the= GNU Lesser General //// +//// Public License along with this source;= if not, download it //// +//// from http://www.opencores.org/lgpl.sht= ml //// +//// = //// +///////////////////////////////////////////= /////////////////////////// +// +// +// $Log: or1200_du.v,v $ +// Revision 2.0 2010/06/30 11:00:00 ORSoC= +// Minor update: +// Bugs fixed. + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on +`include "or1200_defines.v" + +// +// Debug unit +// + +module or1200_du( + // RISC Internal Interface + clk, rst, + dcpu_cycstb_i, dcpu_we_i, dcpu_adr_i, dcpu_dat_lsu, + dcpu_dat_dc, icpu_cycstb_i, + ex_freeze, branch_op, ex_insn, id_pc, + spr_dat_npc, rf_dataw, + du_dsr, du_dmr1, du_stall, du_addr, du_dat_i, du_dat_o, + du_read, du_write, du_except_stop, du_hwbkpt, du_flush_pipe, + spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o, + + // External Debug Interface + dbg_stall_i, dbg_ewt_i, dbg_lss_o, dbg_is_o, dbg_wp_o, dbg_bp_o, + dbg_stb_i, dbg_we_i, dbg_adr_i, dbg_dat_i, dbg_dat_o, dbg_ack_o +); + +parameter dw =3D `OR1200_OPERAND_WIDTH; +parameter aw =3D `OR1200_OPERAND_WIDTH; + +// +// I/O +// + +// +// RISC Internal Interface +// +input clk; // Clock +input rst; // Reset +input dcpu_cycstb_i; // LSU status +input dcpu_we_i; // LSU status +input [31:0] dcpu_adr_i; // LSU addr +input [31:0] dcpu_dat_lsu; // LSU store data +input [31:0] dcpu_dat_dc; // LSU load data +input [`OR1200_FETCHOP_WIDTH-1:+ + diff --git a/autotests/input/syntax/vhdl/results/light52_muldiv.vhdl.refere= nce.html b/autotests/input/syntax/vhdl/results/light52_muldiv.vhdl.referenc= e.html new file mode 100644 index 0000000..1b51ff5 --- /dev/null +++ b/autotests/input/syntax/vhdl/results/light52_muldiv.vhdl.reference.html @@ -0,0 +1,257 @@ + + + + + + +0] icpu_cycstb_i; // IFETCH unit status +input ex_freeze; // EX stage freeze +input [`OR1200_BRANCHOP_WIDTH-1: ; + casez (du_except_stop) + 14'b1?_????_????_????: + except_stop[`OR1200_DU_DRR_TTE] = =3D 1'b1; + 14'b01_????_????_????: begin + except_stop[`OR1200_DU_DRR_IE] = =3D 1'b1; + end + 14'b00_1???_????_????: begin + except_stop[`OR1200_DU_DRR_IME] = =3D 1'b1; + end + 14'b00_01??_????_????: + except_stop[`OR1200_DU_DRR_IPFE] = =3D 1'b1; + 14'b00_001?_????_????: begin + except_stop[`OR1200_DU_DRR_BUSEE]= =3D 1'b1; + end + 14'b00_0001_????_????: + except_stop[`OR1200_DU_DRR_IIE] = =3D 1'b1; + 14'b00_0000_1???_????: begin + except_stop[`OR1200_DU_DRR_AE] = =3D 1'b1; + end + 14'b00_0000_01??_????: begin + except_stop[`OR1200_DU_DRR_DME] = =3D 1'b1; + end + 14'b00_0000_001?_????: + except_stop[`OR1200_DU_DRR_DPFE] = =3D 1'b1; + 14'b00_0000_0001_????: + except_stop[`OR1200_DU_DRR_BUSEE]= =3D 1'b1; + 14'b00_0000_0000_1???: begin + except_stop[`OR1200_DU_DRR_RE] = =3D 1'b1; + end + 14'b00_0000_0000_01??: begin + except_stop[`OR1200_DU_DRR_TE] = =3D 1'b1 & ~ex_freeze_q; + end + 14'b00_0000_0000_001?: begin + except_stop[`OR1200_DU_DRR_FPE] =3D 1'b1; + end = + 14'b00_0000_0000_0001: + except_stop[`OR1200_DU_DRR_SCE] = =3D 1'b1 & ~ex_freeze_q; + default: + except_stop =3D 14'b00_0000_0000_0000; + endcase // casez (du_except_stop)= span> +end + +// +// dbg_bp_o is registered +// +assign dbg_bp_o =3D dbg_bp_r; + +// +// Breakpoint activation register +// +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dbg_bp_r <=3D 1'b0; + else if (!ex_freeze) + dbg_bp_r <=3D |except_stop +`ifdef OR1200_DU_DMR1_ST + | ~((ex_insn[31:26] =3D=3D `OR1200_OR32_NOP) & ex_insn[16]) & dmr1[`OR1200_DU_DMR1_S= T] +`endif +`ifdef OR1200_DU_DMR1_BT + | (branch_op !=3D `= OR1200_BRANCHOP_NOP) & (branch_op !=3D `OR1200_BRANCHOP_RFE) & dmr1[`OR1200_DU_DMR1_BT] +`endif + ; + else + dbg_bp_r <=3D |except_stop; + +// +// Write to DMR1 +// +`ifdef OR1200_DU_DMR1 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dmr1 <=3D 25'h000_0000; + else if (dmr1_sel && spr_write) +`ifdef OR1200_DU_HWBKPTS + dmr1 <=3D spr_dat_i[24:0]; +`else + dmr1 <=3D {1'b0, spr_dat_i[0] branch_op; // Branch op +input [dw-1:0] ex_insn; // EX insn +input [31:0] id_pc; // insn fetch EA +input [31:0] spr_dat_npc; // Next PC (for trace) +input [31:0] rf_dataw; // ALU result (for trace) +output [`OR1200_DU_DSR_WIDTH-1: 0] du_dsr; // DSR +output [24: 0] du_dmr1; +output du_stall; // Debug Unit Stall +output [aw-1:0] du_addr; // Debug Unit Address +input [dw-1:0] du_dat_i; // Debug Unit Data In +output [dw-1:0] du_dat_o; // Debug Unit Data Out +output du_read; // Debug Unit Read Enable +output du_write; // Debug Unit Write Enable +input [13:0] du_except_stop; +// +`ifdef OR1200_DU_DWCR1 +reg [= 31:0] dwcr1; +`else +wire [31:0] dwcr1; +`endif + +// +// Internal wires +// +wire dmr1_sel; // DMR1 select +wire dmr2_sel; // DMR2 select +wire dsr_sel; // DSR select +wire drr_sel; // DRR select +wire dvr0_sel, + dvr1_sel, + dvr2_sel, + dvr3_sel, + dvr4_sel, + dvr5_sel, + dvr6_sel, + dvr7_sel; // DVR selects +wire dcr0_sel, + dcr1_sel, + dcr2_sel, + dcr3_sel, + dcr4_sel, + dcr5_sel, + dcr6_sel, + dcr7_sel; // DCR selects +wire dwcr0_sel, + dwcr1_sel; // DWCR selects +reg dbg_bp_r; +reg ex_freeze_q; +`ifdef OR1200_DU_HWBKPTS +reg [= 31:0] match_cond0_ct; +reg [= 31:0] match_cond1_ct; +reg [= 31:0] match_cond2_ct; +reg [= 31:0] match_cond3_ct; +reg [= 31:0] match_cond4_ct; +reg [= 31:0] match_cond5_ct; +reg [= 31:0] match_cond6_ct; +reg [= 31:0] match_cond7_ct; +reg match_cond0_stb; +reg match_cond1_stb; +reg match_cond2_stb; +reg match_cond3_stb; +reg match_cond4_stb; +reg match_cond5_stb; +reg match_cond6_stb; +reg match_cond7_stb; +reg match0; +reg match1; +reg match2; +reg match3; +reg match4; +reg match5; +reg match6; +reg match7; +reg wpcntr0_match; +reg wpcntr1_match; +reg incr_wpcntr0; +reg incr_wpcntr1; +reg [= 10:0] wp; +`endif +wire du_hwbkpt; +reg du_hwbkpt_hold; +`ifdef OR1200_DU_READREGS +reg [= 31:0] spr_dat_o; +`endif +reg [= 13:0] except_stop; // Exceptions that stop because of DSR +`ifdef OR1200_DU_TB_IMPLEMENTED +wire tb_enw; +reg [= 7:0] tb_wadr; +reg [= 31:0] tb_timstmp; +`endif +wire [31:0] tbia_dat_o; +wire [31:0] tbim_dat_o; +wire [31:0] tbar_dat_o; +wire [31:0] tbts_dat_o; + +// +// DU registers address decoder +// +`ifdef OR1200_DU_DMR1 +assign dmr1_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DMR1)); +`endif +`ifdef OR1200_DU_DMR2 +assign dmr2_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DMR2)); +`endif +`ifdef OR1200_DU_DSR +assign dsr_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DSR)); +`endif +`ifdef OR1200_DU_DRR +assign drr_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DRR)); +`endif +`ifdef OR1200_DU_DVR0 +assign dvr0_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DVR0)); +`endif +`ifdef OR1200_DU_DVR1 +assign dvr1_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DVR1)); +`endif +`ifdef OR1200_DU_DVR2 +assign dvr2_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DVR2)); +`endif +`ifdef OR1200_DU_DVR3 +assign dvr3_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DVR3)); +`endif +`ifdef OR1200_DU_DVR4 +assign dvr4_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DVR4)); +`endif +`ifdef OR1200_DU_DVR5 +assign dvr5_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DVR5)); +`endif +`ifdef OR1200_DU_DVR6 +assign dvr6_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DVR6)); +`endif +`ifdef OR1200_DU_DVR7 +assign dvr7_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DVR7)); +`endif +`ifdef OR1200_DU_DCR0 +assign dcr0_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DCR0)); +`endif +`ifdef OR1200_DU_DCR1 +assign dcr1_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DCR1)); +`endif +`ifdef OR1200_DU_DCR2 +assign dcr2_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DCR2)); +`endif +`ifdef OR1200_DU_DCR3 +assign dcr3_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DCR3)); +`endif +`ifdef OR1200_DU_DCR4 +assign dcr4_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DCR4)); +`endif +`ifdef OR1200_DU_DCR5 +assign dcr5_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DCR5)); +`endif +`ifdef OR1200_DU_DCR6 +assign dcr6_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DCR6)); +`endif +`ifdef OR1200_DU_DCR7 +assign dcr7_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DCR7)); +`endif +`ifdef OR1200_DU_DWCR0 +assign dwcr0_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DWCR0)); +`endif +`ifdef OR1200_DU_DWCR1 +assign dwcr1_sel =3D (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] =3D=3D `OR1200_DU_DWCR1)); +`endif + +// Track previous ex_freeze to detect when = signals are updated +always @(posedge clk) + ex_freeze_q <=3D ex_freeze; + +// +// Decode started exception +// +// du_except_stop comes from or1200_except<= /span> +// +always @(du_except_stop or ex= _freeze_q) begin + except_stop =3D 14'b00_0000_0000_0000// Exception masked by DSR +output du_hwbkpt; // Cause trap exception (HW Breakpoints) +output du_flush_pipe; // Cause pipeline flush and pc<-npc +input spr_cs; // SPR Chip Select +input spr_write; // SPR Read/Write +input [aw-1:0] spr_addr; // SPR Address +input [dw-1:0] spr_dat_i; // SPR Data Input +output [dw-1:0] spr_dat_o; // SPR Data Output + +// +// External Debug Interface +// +input dbg_stall_i; // External Stall Input +input dbg_ewt_i; // External Watchpoint Trigger Input +output [3:0] dbg_lss_o; // External Load/Store Unit Status +output [1:0] dbg_is_o; // External Insn Fetch Status +output [10:0] dbg_wp_o; // Watchpoints Outputs +output dbg_bp_o; // Breakpoint Output +input dbg_stb_i; // External Address/Data Strobe +input dbg_we_i; // External Write Enable +input [aw-1:0] dbg_adr_i; // External Address Input +input [dw-1:0] dbg_dat_i; // External Data Input +output [dw-1:0] dbg_dat_o; // External Data Output +output dbg_ack_o; // External Data Acknowledge (not WB compatible) +reg [dw-1:0] dbg_dat_o; // External Data Output +reg dbg_ack_o; // External Data Acknowledge (not WB compatible) + + +// +// Some connections go directly from the CP= U through DU to Debug I/F +// +`ifdef OR1200_DU_STATUS_UNIMPLEMENTED +assign dbg_lss_o =3D 4'b0000; + +reg [= 1:0] dbg_is_o; +// +// Show insn activity (temp, must be remove= d) +// +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dbg_is_o <=3D 2'b00; + else if (!ex_freeze & ~((ex_insn[31:26] =3D=3D `OR1200_OR32_NOP) & ex_insn[16])) + dbg_is_o <=3D ~dbg_is_o; +`ifdef UNUSED +assign dbg_is_o =3D 2'b00; +`endif +`else +assign dbg_lss_o =3D dcpu_cycstb_i ? {dcpu_we_i, 3'b000} : 4'b0000; +assign dbg_is_o =3D {1'b0, ic= pu_cycstb_i}; +`endif +assign dbg_wp_o =3D 11'b000_0000_000= 0; + +// +// Some connections go directly from Debug = I/F through DU to the CPU +// +assign du_stall =3D dbg_stall_i; +assign du_addr =3D dbg_adr_i; +assign du_dat_o =3D dbg_dat_i; +assign du_read =3D dbg_stb_i && !dbg_we_i; +assign du_write =3D dbg_stb_i && dbg_we_i; + +// +// After a sw breakpoint, the replaced inst= ruction need to be executed. +// We flush the entire pipeline and set the= pc to the current address +// to execute the restored address. +// + +reg du_flush_pipe_r; +reg dbg_stall_i_r; + +assign du_flush_pipe =3D du_flush_pipe_r; + +// +// Register du_flush_pipe +// +always @(posedge clk or `OR1200_RST_EVENT rst) begin + if (rst =3D=3D `OR1200_RST_VALUE) begin + du_flush_pipe_r <=3D 1'b0; + end + else begin + du_flush_pipe_r <=3D (dbg_stall_i_r && !dbg_stall_i &&= amp; |du_except_stop); + end +end + +// +// Detect dbg_stall falling edge +// +always @(posedge clk or `OR1200_RST_EVENT rst) begin + if (rst =3D=3D `OR1200_RST_VALUE) begin + dbg_stall_i_r <=3D 1'b0; + end + else begin + dbg_stall_i_r <=3D dbg_stall_i; + end +end + +reg dbg_ack; +// +// Generate acknowledge -- just delay stb s= ignal +// +always @(posedge clk or `OR1200_RST_EVENT rst) begin + if (rst =3D=3D `OR1200_RST_VALUE) begin + dbg_ack <=3D 1'b0; + dbg_ack_o <=3D 1'b0; + end + else begin + dbg_ack <=3D dbg_stb_i; // valid w= hen du_dat_i + dbg_ack_o <=3D dbg_ack & dbg_stb_i; // valid when dbg_dat_o + end +end + +// +// Register data output +// +always @(posedge clk) + dbg_dat_o <=3D du_dat_i; + +`ifdef OR1200_DU_IMPLEMENTED + +// +// Debug Mode Register 1 +// +`ifdef OR1200_DU_DMR1 +reg [= 24:0] dmr1; // DMR1 implemented +`else +wire [24:0] dmr1; // DMR1 not implemented +`endif +assign du_dmr1 =3D dmr1; + +// +// Debug Mode Register 2 +// +`ifdef OR1200_DU_DMR2 +reg [= 23:0] dmr2; // DMR2 implemented +`else +wire [23:0] dmr2; // DMR2 not implemented +`endif + +// +// Debug Stop Register +// +`ifdef OR1200_DU_DSR +reg [= `OR1200_DU_DSR_WIDTH-1:0] dsr; // D= SR implemented +`else +wire [`OR1200_DU_DSR_WIDTH-1:0] dsr; // = DSR not implemented +`endif + +// +// Debug Reason Register +// +`ifdef OR1200_DU_DRR +reg [= 13:0] drr; // DRR implemented +`else +wire [13:0] drr; // DRR not implemented +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR0 +reg [= 31:0] dvr0; +`else +wire [31:0] dvr0; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR1 +reg [= 31:0] dvr1; +`else +wire [31:0] dvr1; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR2 +reg [= 31:0] dvr2; +`else +wire [31:0] dvr2; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR3 +reg [= 31:0] dvr3; +`else +wire [31:0] dvr3; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR4 +reg [= 31:0] dvr4; +`else +wire [31:0] dvr4; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR5 +reg [= 31:0] dvr5; +`else +wire [31:0] dvr5; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR6 +reg [= 31:0] dvr6; +`else +wire [31:0] dvr6; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR7 +reg [= 31:0] dvr7; +`else +wire [31:0] dvr7; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR0 +reg [= 7:0] dcr0; +`else +wire [7:0] dcr0; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR1 +reg [= 7:0] dcr1; +`else +wire [7:0] dcr1; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR2 +reg [= 7:0] dcr2; +`else +wire [7:0] dcr2; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR3 +reg [= 7:0] dcr3; +`else +wire [7:0] dcr3; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR4 +reg [= 7:0] dcr4; +`else +wire [7:0] dcr4; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR5 +reg [= 7:0] dcr5; +`else +wire [7:0] dcr5; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR6 +reg [= 7:0] dcr6; +`else +wire [7:0] dcr6; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR7 +reg [= 7:0] dcr7; +`else +wire [7:0] dcr7; +`endif + +// +// Debug Watchpoint Counter Register 0 +// +`ifdef OR1200_DU_DWCR0 +reg [= 31:0] dwcr0; +`else +wire [31:0] dwcr0; +`endif + +// +// Debug Watchpoint Counter Register 123 :22], 22'h00_0000}; +`endif +`else +assign dmr1 =3D 25'h000_0000; +`endif + +// +// Write to DMR2 +// +`ifdef OR1200_DU_DMR2 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dmr2 <=3D 24'h00_0000; + else if (dmr2_sel && spr_write) + dmr2 <=3D spr_dat_i[23:0]; +`else +assign dmr2 =3D 24'h00_0000; +`endif + +// +// Write to DSR +// +`ifdef OR1200_DU_DSR +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dsr <=3D {`OR1200_DU_DSR_WIDTH{= 1'b0}}; + else if (dsr_sel && spr_write) + dsr <=3D spr_dat_i[`OR1200_DU_DSR_WID= TH-1:0]; +`else +assign dsr =3D {`OR1200_DU_DSR_WIDTH= {1'b0}}; +`endif + +// +// Write to DRR +// +`ifdef OR1200_DU_DRR +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + drr <=3D 14'b0; + else if (drr_sel && spr_write) + drr <=3D spr_dat_i[13:0]; + else + drr <=3D drr | except_stop; +`else +assign drr =3D 14'b0; +`endif + +// +// Write to DVR0 +// +`ifdef OR1200_DU_DVR0 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dvr0 <=3D 32'h0000_0000; + else if (dvr0_sel && spr_write) + dvr0 <=3D spr_dat_i[31:0]; +`else +assign dvr0 =3D 32'h0000_0000; +`endif + +// +// Write to DVR1 +// +`ifdef OR1200_DU_DVR1 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dvr1 <=3D 32'h0000_0000; + else if (dvr1_sel && spr_write) + dvr1 <=3D spr_dat_i[31:0]; +`else +assign dvr1 =3D 32'h0000_0000; +`endif + +// +// Write to DVR2 +// +`ifdef OR1200_DU_DVR2 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dvr2 <=3D 32'h0000_0000; + else if (dvr2_sel && spr_write) + dvr2 <=3D spr_dat_i[31:0]; +`else +assign dvr2 =3D 32'h0000_0000; +`endif + +// +// Write to DVR3 +// +`ifdef OR1200_DU_DVR3 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dvr3 <=3D 32'h0000_0000; + else if (dvr3_sel && spr_write) + dvr3 <=3D spr_dat_i[31:0]; +`else +assign dvr3 =3D 32'h0000_0000; +`endif + +// +// Write to DVR4 +// +`ifdef OR1200_DU_DVR4 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dvr4 <=3D 32'h0000_0000; + else if (dvr4_sel && spr_write) + dvr4 <=3D spr_dat_i[31:0]; +`else +assign dvr4 =3D 32'h0000_0000; +`endif + +// +// Write to DVR5 +// +`ifdef OR1200_DU_DVR5 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dvr5 <=3D 32'h0000_0000; + else if (dvr5_sel && spr_write) + dvr5 <=3D spr_dat_i[31:0]; +`else +assign dvr5 =3D 32'h0000_0000; +`endif + +// +// Write to DVR6 +// +`ifdef OR1200_DU_DVR6 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dvr6 <=3D 32'h0000_0000; + else if (dvr6_sel && spr_write) + dvr6 <=3D spr_dat_i[31:0]; +`else +assign dvr6 =3D 32'h0000_0000; +`endif + +// +// Write to DVR7 +// +`ifdef OR1200_DU_DVR7 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dvr7 <=3D 32'h0000_0000; + else if (dvr7_sel && spr_write) + dvr7 <=3D spr_dat_i[31:0]; +`else +assign dvr7 =3D 32'h0000_0000; +`endif + +// +// Write to DCR0 +// +`ifdef OR1200_DU_DCR0 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dcr0 <=3D 8'h00; + else if (dcr0_sel && spr_write) + dcr0 <=3D spr_dat_i[7:0]; +`else +assign dcr0 =3D 8'h00; +`endif + +// +// Write to DCR1 +// +`ifdef OR1200_DU_DCR1 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dcr1 <=3D 8'h00; + else if (dcr1_sel && spr_write) + dcr1 <=3D spr_dat_i[7:0]; +`else +assign dcr1 =3D 8'h00; +`endif + +// +// Write to DCR2 +// +`ifdef OR1200_DU_DCR2 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dcr2 <=3D 8'h00; + else if (dcr2_sel && spr_write) + dcr2 <=3D spr_dat_i[7:0]; +`else +assign dcr2 =3D 8'h00; +`endif + +// +// Write to DCR3 +// +`ifdef OR1200_DU_DCR3 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dcr3 <=3D 8'h00; + else if (dcr3_sel && spr_write) + dcr3 <=3D spr_dat_i[7:0]; +`else +assign dcr3 =3D 8'h00; +`endif + +// +// Write to DCR4 +// +`ifdef OR1200_DU_DCR4 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dcr4 <=3D 8'h00; + else if (dcr4_sel && spr_write) + dcr4 <=3D spr_dat_i[7:0]; +`else +assign dcr4 =3D 8'h00; +`endif + +// +// Write to DCR5 +// +`ifdef OR1200_DU_DCR5 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dcr5 <=3D 8'h00; + else if (dcr5_sel && spr_write) + dcr5 <=3D spr_dat_i[7:0]; +`else +assign dcr5 =3D 8'h00; +`endif + +// +// Write to DCR6 +// +`ifdef OR1200_DU_DCR6 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dcr6 <=3D 8'h00; + else if (dcr6_sel && spr_write) + dcr6 <=3D spr_dat_i[7:0]; +`else +assign dcr6 =3D 8'h00; +`endif + +// +// Write to DCR7 +// +`ifdef OR1200_DU_DCR7 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dcr7 <=3D 8'h00; + else if (dcr7_sel && spr_write) + dcr7 <=3D spr_dat_i[7:0]; +`else +assign dcr7 =3D 8'h00; +`endif + +// +// Write to DWCR0 +// +`ifdef OR1200_DU_DWCR0 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dwcr0 <=3D 32'h0000_0000; + else if (dwcr0_sel && spr_write) + dwcr0 <=3D spr_dat_i[31:0]; + else if (incr_wpcntr0) + dwcr0[`OR1200_DU_DWCR_COUNT] <= =3D dwcr0[`OR1200_DU_DWCR_COUNT] + <= span style=3D'color:#b08000;'>16'h0001; +`else +assign dwcr0 =3D 32'h0000_0000; +`endif + +// +// Write to DWCR1 +// +`ifdef OR1200_DU_DWCR1 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + dwcr1 <=3D 32'h0000_0000; + else if (dwcr1_sel && spr_write) + dwcr1 <=3D spr_dat_i[31:0]; + else if (incr_wpcntr1) + dwcr1[`OR1200_DU_DWCR_COUNT] <= =3D dwcr1[`OR1200_DU_DWCR_COUNT] + <= span style=3D'color:#b08000;'>16'h0001; +`else +assign dwcr1 =3D 32'h0000_0000; +`endif + +// +// Read DU registers +// +`ifdef OR1200_DU_READREGS +always @(spr_addr or dsror drr or<= /span> dmr1 or dmr2 + or dvr0 or dvr1 or dvr2 or dvr3 or dvr4 + or dvr5 or dvr6 or dvr7 + or dcr0 or dcr1 or dcr2 or dcr3 or dcr4 + or dcr5 or dcr6 or dcr7 + or dwcr0 or dwcr1 +`ifdef OR1200_DU_TB_IMPLEMENTED + or tb_wadr or tbia_dat_o or tbim_d= at_o + or tbar_dat_o or tbts_dat_o +`endif + ) + casez (spr_addr[`OR1200_DUOFS_BITS<= /span>]) // synopsys parallel_case +`ifdef OR1200_DU_DVR0 + `OR1200_DU_DVR0: + spr_dat_o =3D dvr0; +`endif +`ifdef OR1200_DU_DVR1 + `OR1200_DU_DVR1: + spr_dat_o =3D dvr1; +`endif +`ifdef OR1200_DU_DVR2 + `OR1200_DU_DVR2: + spr_dat_o =3D dvr2; +`endif +`ifdef OR1200_DU_DVR3 + `OR1200_DU_DVR3: + spr_dat_o =3D dvr3; +`endif +`ifdef OR1200_DU_DVR4 + `OR1200_DU_DVR4: + spr_dat_o =3D dvr4; +`endif +`ifdef OR1200_DU_DVR5 + `OR1200_DU_DVR5: + spr_dat_o =3D dvr5; +`endif +`ifdef OR1200_DU_DVR6 + `OR1200_DU_DVR6: + spr_dat_o =3D dvr6; +`endif +`ifdef OR1200_DU_DVR7 + `OR1200_DU_DVR7: + spr_dat_o =3D dvr7; +`endif +`ifdef OR1200_DU_DCR0 + `OR1200_DU_DCR0: + spr_dat_o =3D {24'h00_0000, dcr0}; +`endif +`ifdef OR1200_DU_DCR1 + `OR1200_DU_DCR1: + spr_dat_o =3D {24'h00_0000, dcr1}; +`endif +`ifdef OR1200_DU_DCR2 + `OR1200_DU_DCR2: + spr_dat_o =3D {24'h00_0000, dcr2}; +`endif +`ifdef OR1200_DU_DCR3 + `OR1200_DU_DCR3: + spr_dat_o =3D {24'h00_0000, dcr3}; +`endif +`ifdef OR1200_DU_DCR4 + `OR1200_DU_DCR4: + spr_dat_o =3D {24'h00_0000, dcr4}; +`endif +`ifdef OR1200_DU_DCR5 + `OR1200_DU_DCR5: + spr_dat_o =3D {24'h00_0000, dcr5}; +`endif +`ifdef OR1200_DU_DCR6 + `OR1200_DU_DCR6: + spr_dat_o =3D {24'h00_0000, dcr6}; +`endif +`ifdef OR1200_DU_DCR7 + `OR1200_DU_DCR7: + spr_dat_o =3D {24'h00_0000, dcr7}; +`endif +`ifdef OR1200_DU_DMR1 + `OR1200_DU_DMR1: + spr_dat_o =3D {7'h00, dmr1}; +`endif +`ifdef OR1200_DU_DMR2 + `OR1200_DU_DMR2: + spr_dat_o =3D {8'h00, dmr2}; +`endif +`ifdef OR1200_DU_DWCR0 + `OR1200_DU_DWCR0: + spr_dat_o =3D dwcr0; +`endif +`ifdef OR1200_DU_DWCR1 + `OR1200_DU_DWCR1: + spr_dat_o =3D dwcr1; +`endif +`ifdef OR1200_DU_DSR + `OR1200_DU_DSR: + spr_dat_o =3D {18'b0, dsr}; +`endif +`ifdef OR1200_DU_DRR + `OR1200_DU_DRR: + spr_dat_o =3D {18'b0, drr}; +`endif +`ifdef OR1200_DU_TB_IMPLEMENTED + `OR1200_DU_TBADR: + spr_dat_o =3D {24'h000000, tb_wad= r}; + `OR1200_DU_TBIA: + spr_dat_o =3D tbia_dat_o; + `OR1200_DU_TBIM: + spr_dat_o =3D tbim_dat_o; + `OR1200_DU_TBAR: + spr_dat_o =3D tbar_dat_o; + `OR1200_DU_TBTS: + spr_dat_o =3D tbts_dat_o; +`endif + default: + spr_dat_o =3D 32'h0000_0000; + endcase +`endif + +// +// DSR alias +// +assign du_dsr =3D dsr; + +`ifdef OR1200_DU_HWBKPTS + +// +// Compare To What (Match Condition 0) +// +always @(dcr0 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr0[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b001: match_cond0_ct =3D id_pc; = // insn fetch EA + 3'b010: match_cond0_ct =3D dcpu_ad= r_i; // load EA + 3'b011: match_cond0_ct =3D dcpu_ad= r_i; // store EA + 3'b100: match_cond0_ct =3D dcpu_da= t_dc; // load data + 3'b101: match_cond0_ct =3D dcpu_da= t_lsu; // store data + 3'b110: match_cond0_ct =3D dcpu_ad= r_i; // load/store EA + default:match_cond0_ct =3D dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 0) +// +always @(dcr0 or dcpu_cycstb_= i) + case (dcr0[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b000: match_cond0_stb =3D 1'b0; //com= parison disabled + 3'b001: match_cond0_stb =3D 1'b1; // in= sn fetch EA + default:match_cond0_stb =3D dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 0 +// +always @(match_cond0_stb or d= cr0 or dvr0 or match_cond0_ct) + casex ({match_cond0_stb, dcr0[`OR12= 00_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match0 =3D 1'b0; + 4'b1_001: match0 =3D + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC ]), match_cond0_ct[30:0= ]} =3D=3D + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_010: match0 =3D = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC ]), match_cond0_ct[30:0= ]} < + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_011: match0 =3D = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC ]), match_cond0_ct[30:0= ]} <=3D + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_100: match0 =3D = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC ]), match_cond0_ct[30:0= ]} > + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_101: match0 =3D = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC ]), match_cond0_ct[30:0= ]} >=3D + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_110: match0 =3D = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC ]), match_cond0_ct[30:0= ]} !=3D + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + endcase + +// +// Watchpoint 0 +// +always @(dmr1 or match0) + case (dmr1[`OR1200_DU_DMR1_CW0]) + 2'b00: wp[0] =3D match0; + 2'b01: wp[0] =3D match0; + 2'b10: wp[0] =3D match0; + 2'b11: wp[0] =3D 1'b0; + endcase + +// +// Compare To What (Match Condition 1) +// +always @(dcr1 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr1[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b001: match_cond1_ct =3D id_pc; = // insn fetch EA + 3'b010: match_cond1_ct =3D dcpu_ad= r_i; // load EA + 3'b011: match_cond1_ct =3D dcpu_ad= r_i; // store EA + 3'b100: match_cond1_ct =3D dcpu_da= t_dc; // load data + 3'b101: match_cond1_ct =3D dcpu_da= t_lsu; // store data + 3'b110: match_cond1_ct =3D dcpu_ad= r_i; // load/store EA + default:match_cond1_ct =3D dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 1) +// +always @(dcr1 or dcpu_cycstb_= i) + case (dcr1[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b000: match_cond1_stb =3D 1'b0; //com= parison disabled + 3'b001: match_cond1_stb =3D 1'b1; // in= sn fetch EA + default:match_cond1_stb =3D dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 1 +// +always @(match_cond1_stb or d= cr1 or dvr1 or match_cond1_ct) + casex ({match_cond1_stb, dcr1[`OR12= 00_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match1 =3D 1'b0; + 4'b1_001: match1 =3D + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC ]), match_cond1_ct[30:0= ]} =3D=3D + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_010: match1 =3D = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC ]), match_cond1_ct[30:0= ]} < + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_011: match1 =3D = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC ]), match_cond1_ct[30:0= ]} <=3D + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_100: match1 =3D = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC ]), match_cond1_ct[30:0= ]} > + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_101: match1 =3D = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC ]), match_cond1_ct[30:0= ]} >=3D + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_110: match1 =3D = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC ]), match_cond1_ct[30:0= ]} !=3D + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + endcase + +// +// Watchpoint 1 +// +always @(dmr1 or match1 or wp) + case (dmr1[`OR1200_DU_DMR1_CW1]) + 2'b00: wp[1] =3D match1; + 2'b01: wp[1] =3D match1 & wp[0]; + 2'b10: wp[1] =3D match1 | wp[0]; + 2'b11: wp[1] =3D 1'b0; + endcase + +// +// Compare To What (Match Condition 2) +// +always @(dcr2 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr2[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b001: match_cond2_ct =3D id_pc; = // insn fetch EA + 3'b010: match_cond2_ct =3D dcpu_ad= r_i; // load EA + 3'b011: match_cond2_ct =3D dcpu_ad= r_i; // store EA + 3'b100: match_cond2_ct =3D dcpu_da= t_dc; // load data + 3'b101: match_cond2_ct =3D dcpu_da= t_lsu; // store data + 3'b110: match_cond2_ct =3D dcpu_ad= r_i; // load/store EA + default:match_cond2_ct =3D dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 2) +// +always @(dcr2 or dcpu_cycstb_= i) + case (dcr2[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b000: match_cond2_stb =3D 1'b0; //com= parison disabled + 3'b001: match_cond2_stb =3D 1'b1; // in= sn fetch EA + default:match_cond2_stb =3D dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 2 +// +always @(match_cond2_stb or d= cr2 or dvr2 or match_cond2_ct) + casex ({match_cond2_stb, dcr2[`OR12= 00_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match2 =3D 1'b0; + 4'b1_001: match2 =3D + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC ]), match_cond2_ct[30:0= ]} =3D=3D + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_010: match2 =3D = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC ]), match_cond2_ct[30:0= ]} < + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_011: match2 =3D = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC ]), match_cond2_ct[30:0= ]} <=3D + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_100: match2 =3D = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC ]), match_cond2_ct[30:0= ]} > + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_101: match2 =3D = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC ]), match_cond2_ct[30:0= ]} >=3D + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_110: match2 =3D = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC ]), match_cond2_ct[30:0= ]} !=3D + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + endcase + +// +// Watchpoint 2 +// +always @(dmr1 or match2 or wp) + case (dmr1[`OR1200_DU_DMR1_CW2]) + 2'b00: wp[2] =3D match2; + 2'b01: wp[2] =3D match2 & wp[1]; + 2'b10: wp[2] =3D match2 | wp[1]; + 2'b11: wp[2] =3D 1'b0; + endcase + +// +// Compare To What (Match Condition 3) +// +always @(dcr3 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr3[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b001: match_cond3_ct =3D id_pc; = // insn fetch EA + 3'b010: match_cond3_ct =3D dcpu_ad= r_i; // load EA + 3'b011: match_cond3_ct =3D dcpu_ad= r_i; // store EA + 3'b100: match_cond3_ct =3D dcpu_da= t_dc; // load data + 3'b101: match_cond3_ct =3D dcpu_da= t_lsu; // store data + 3'b110: match_cond3_ct =3D dcpu_ad= r_i; // load/store EA + default:match_cond3_ct =3D dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 3) +// +always @(dcr3 or dcpu_cycstb_= i) + case (dcr3[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b000: match_cond3_stb =3D 1'b0; //com= parison disabled + 3'b001: match_cond3_stb =3D 1'b1; // in= sn fetch EA + default:match_cond3_stb =3D dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 3 +// +always @(match_cond3_stb or d= cr3 or dvr3 or match_cond3_ct) + casex ({match_cond3_stb, dcr3[`OR12= 00_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match3 =3D 1'b0; + 4'b1_001: match3 =3D + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC ]), match_cond3_ct[30:0= ]} =3D=3D + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_010: match3 =3D = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC ]), match_cond3_ct[30:0= ]} < + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_011: match3 =3D = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC ]), match_cond3_ct[30:0= ]} <=3D + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_100: match3 =3D = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC ]), match_cond3_ct[30:0= ]} > + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_101: match3 =3D = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC ]), match_cond3_ct[30:0= ]} >=3D + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_110: match3 =3D = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC ]), match_cond3_ct[30:0= ]} !=3D + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + endcase + +// +// Watchpoint 3 +// +always @(dmr1 or match3 or wp) + case (dmr1[`OR1200_DU_DMR1_CW3]) + 2'b00: wp[3] =3D match3; + 2'b01: wp[3] =3D match3 & wp[2]; + 2'b10: wp[3] =3D match3 | wp[2]; + 2'b11: wp[3] =3D 1'b0; + endcase + +// +// Compare To What (Match Condition 4) +// +always @(dcr4 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr4[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b001: match_cond4_ct =3D id_pc; = // insn fetch EA + 3'b010: match_cond4_ct =3D dcpu_ad= r_i; // load EA + 3'b011: match_cond4_ct =3D dcpu_ad= r_i; // store EA + 3'b100: match_cond4_ct =3D dcpu_da= t_dc; // load data + 3'b101: match_cond4_ct =3D dcpu_da= t_lsu; // store data + 3'b110: match_cond4_ct =3D dcpu_ad= r_i; // load/store EA + default:match_cond4_ct =3D dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 4) +// +always @(dcr4 or dcpu_cycstb_= i) + case (dcr4[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b000: match_cond4_stb =3D 1'b0; //com= parison disabled + 3'b001: match_cond4_stb =3D 1'b1; // in= sn fetch EA + default:match_cond4_stb =3D dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 4 +// +always @(match_cond4_stb or d= cr4 or dvr4 or match_cond4_ct) + casex ({match_cond4_stb, dcr4[`OR12= 00_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match4 =3D 1'b0; + 4'b1_001: match4 =3D + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC ]), match_cond4_ct[30:0= ]} =3D=3D + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_010: match4 =3D = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC ]), match_cond4_ct[30:0= ]} < + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_011: match4 =3D = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC ]), match_cond4_ct[30:0= ]} <=3D + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_100: match4 =3D = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC ]), match_cond4_ct[30:0= ]} > + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_101: match4 =3D = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC ]), match_cond4_ct[30:0= ]} >=3D + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_110: match4 =3D = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC ]), match_cond4_ct[30:0= ]} !=3D + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + endcase + +// +// Watchpoint 4 +// +always @(dmr1 or match4 or wp) + case (dmr1[`OR1200_DU_DMR1_CW4]) + 2'b00: wp[4] =3D match4; + 2'b01: wp[4] =3D match4 & wp[3]; + 2'b10: wp[4] =3D match4 | wp[3]; + 2'b11: wp[4] =3D 1'b0; + endcase + +// +// Compare To What (Match Condition 5) +// +always @(dcr5 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr5[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b001: match_cond5_ct =3D id_pc; = // insn fetch EA + 3'b010: match_cond5_ct =3D dcpu_ad= r_i; // load EA + 3'b011: match_cond5_ct =3D dcpu_ad= r_i; // store EA + 3'b100: match_cond5_ct =3D dcpu_da= t_dc; // load data + 3'b101: match_cond5_ct =3D dcpu_da= t_lsu; // store data + 3'b110: match_cond5_ct =3D dcpu_ad= r_i; // load/store EA + default:match_cond5_ct =3D dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 5) +// +always @(dcr5 or dcpu_cycstb_= i) + case (dcr5[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b000: match_cond5_stb =3D 1'b0; //com= parison disabled + 3'b001: match_cond5_stb =3D 1'b1; // in= sn fetch EA + default:match_cond5_stb =3D dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 5 +// +always @(match_cond5_stb or d= cr5 or dvr5 or match_cond5_ct) + casex ({match_cond5_stb, dcr5[`OR12= 00_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match5 =3D 1'b0; + 4'b1_001: match5 =3D + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC ]), match_cond5_ct[30:0= ]} =3D=3D + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_010: match5 =3D = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC ]), match_cond5_ct[30:0= ]} < + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_011: match5 =3D = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC ]), match_cond5_ct[30:0= ]} <=3D + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_100: match5 =3D = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC ]), match_cond5_ct[30:0= ]} > + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_101: match5 =3D = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC ]), match_cond5_ct[30:0= ]} >=3D + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_110: match5 =3D = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC ]), match_cond5_ct[30:0= ]} !=3D + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + endcase + +// +// Watchpoint 5 +// +always @(dmr1 or match5 or wp) + case (dmr1[`OR1200_DU_DMR1_CW5]) + 2'b00: wp[5] =3D match5; + 2'b01: wp[5] =3D match5 & wp[4]; + 2'b10: wp[5] =3D match5 | wp[4]; + 2'b11: wp[5] =3D 1'b0; + endcase + +// +// Compare To What (Match Condition 6) +// +always @(dcr6 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr6[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b001: match_cond6_ct =3D id_pc; = // insn fetch EA + 3'b010: match_cond6_ct =3D dcpu_ad= r_i; // load EA + 3'b011: match_cond6_ct =3D dcpu_ad= r_i; // store EA + 3'b100: match_cond6_ct =3D dcpu_da= t_dc; // load data + 3'b101: match_cond6_ct =3D dcpu_da= t_lsu; // store data + 3'b110: match_cond6_ct =3D dcpu_ad= r_i; // load/store EA + default:match_cond6_ct =3D dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 6) +// +always @(dcr6 or dcpu_cycstb_= i) + case (dcr6[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b000: match_cond6_stb =3D 1'b0; //com= parison disabled + 3'b001: match_cond6_stb =3D 1'b1; // in= sn fetch EA + default:match_cond6_stb =3D dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 6 +// +always @(match_cond6_stb or d= cr6 or dvr6 or match_cond6_ct) + casex ({match_cond6_stb, dcr6[`OR12= 00_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match6 =3D 1'b0; + 4'b1_001: match6 =3D + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC ]), match_cond6_ct[30:0= ]} =3D=3D + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_010: match6 =3D = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC ]), match_cond6_ct[30:0= ]} < + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_011: match6 =3D = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC ]), match_cond6_ct[30:0= ]} <=3D + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_100: match6 =3D = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC ]), match_cond6_ct[30:0= ]} > + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_101: match6 =3D = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC ]), match_cond6_ct[30:0= ]} >=3D + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_110: match6 =3D = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC ]), match_cond6_ct[30:0= ]} !=3D + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + endcase + +// +// Watchpoint 6 +// +always @(dmr1 or match6 or wp) + case (dmr1[`OR1200_DU_DMR1_CW6]) + 2'b00: wp[6] =3D match6; + 2'b01: wp[6] =3D match6 & wp[5]; + 2'b10: wp[6] =3D match6 | wp[5]; + 2'b11: wp[6] =3D 1'b0; + endcase + +// +// Compare To What (Match Condition 7) +// +always @(dcr7 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr7[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b001: match_cond7_ct =3D id_pc; = // insn fetch EA + 3'b010: match_cond7_ct =3D dcpu_ad= r_i; // load EA + 3'b011: match_cond7_ct =3D dcpu_ad= r_i; // store EA + 3'b100: match_cond7_ct =3D dcpu_da= t_dc; // load data + 3'b101: match_cond7_ct =3D dcpu_da= t_lsu; // store data + 3'b110: match_cond7_ct =3D dcpu_ad= r_i; // load/store EA + default:match_cond7_ct =3D dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 7) +// +always @(dcr7 or dcpu_cycstb_= i) + case (dcr7[`OR1200_DU_DCR_CT= ]) // synopsys parallel_case + 3'b000: match_cond7_stb =3D 1'b0; //com= parison disabled + 3'b001: match_cond7_stb =3D 1'b1; // in= sn fetch EA + default:match_cond7_stb =3D dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 7 +// +always @(match_cond7_stb or d= cr7 or dvr7 or match_cond7_ct) + casex ({match_cond7_stb, dcr7[`OR12= 00_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match7 =3D 1'b0; + 4'b1_001: match7 =3D + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC ]), match_cond7_ct[30:0= ]} =3D=3D + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_010: match7 =3D = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC ]), match_cond7_ct[30:0= ]} < + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_011: match7 =3D = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC ]), match_cond7_ct[30:0= ]} <=3D + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_100: match7 =3D = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC ]), match_cond7_ct[30:0= ]} > + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_101: match7 =3D = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC ]), match_cond7_ct[30:0= ]} >=3D + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_110: match7 =3D = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC ]), match_cond7_ct[30:0= ]} !=3D + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + endcase + +// +// Watchpoint 7 +// +always @(dmr1 or match7 or wp) + case (dmr1[`OR1200_DU_DMR1_CW7]) + 2'b00: wp[7] =3D match7; + 2'b01: wp[7] =3D match7 & wp[6]; + 2'b10: wp[7] =3D match7 | wp[6]; + 2'b11: wp[7] =3D 1'b0; + endcase + +// +// Increment Watchpoint Counter 0 +// +always @(wp or dmr2) + if (dmr2[`OR1200_DU_DMR2_WCE0]) + incr_wpcntr0 =3D |(wp & ~dmr2[`OR1200= _DU_DMR2_AWTC]); + else + incr_wpcntr0 =3D 1'b0; + +// +// Match Condition Watchpoint Counter 0 +// +always @(dwcr0) + if (dwcr0[`OR1200_DU_DWCR_MATCH] =3D=3D dwcr0[`OR1200_DU_DWCR_COUNT]) + wpcntr0_match =3D 1'b1; + else + wpcntr0_match =3D 1'b0; + + +// +// Watchpoint 8 +// +always @(dmr1 or wpcntr0_matc= h or wp) + case (dmr1[`OR1200_DU_DMR1_CW8]) + 2'b00: wp[8] =3D wpcntr0_match; + 2'b01: wp[8] =3D wpcntr0_match & wp[= 7]; + 2'b10: wp[8] =3D wpcntr0_match | wp[7]; + 2'b11: wp[8] =3D 1'b0; + endcase + + +// +// Increment Watchpoint Counter 1 +// +always @(wp or dmr2) + if (dmr2[`OR1200_DU_DMR2_WCE1]) + incr_wpcntr1 =3D |(wp & dmr2[`OR1200_= DU_DMR2_AWTC]); + else + incr_wpcntr1 =3D 1'b0; + +// +// Match Condition Watchpoint Counter 1 +// +always @(dwcr1) + if (dwcr1[`OR1200_DU_DWCR_MATCH] =3D=3D dwcr1[`OR1200_DU_DWCR_COUNT]) + wpcntr1_match =3D 1'b1; + else + wpcntr1_match =3D 1'b0; + +// +// Watchpoint 9 +// +always @(dmr1 or wpcntr1_matc= h or wp) + case (dmr1[`OR1200_DU_DMR1_CW9]) + 2'b00: wp[9] =3D wpcntr1_match; + 2'b01: wp[9] =3D wpcntr1_match & wp[= 8]; + 2'b10: wp[9] =3D wpcntr1_match | wp[8]; + 2'b11: wp[9] =3D 1'b0; + endcase + +// +// Watchpoint 10 +// +always @(dmr1 or dbg_ewt_iorwp) + case (dmr1[`OR1200_DU_DMR1_CW10]) + 2'b00: wp[10] =3D dbg_ewt_i; + 2'b01: wp[10] =3D dbg_ewt_i & wp[9= span>]; + 2'b10: wp[10] =3D dbg_ewt_i | wp[9]; + 2'b11: wp[10] =3D 1'b0; + endcase + +`endif + +// +// Watchpoints can cause trap exception +// +`ifdef OR1200_DU_HWBKPTS +assign du_hwbkpt =3D |(wp & dmr2[`OR1200_DU_DMR2_WGB]) | du_hwbkpt_hold | (dbg_bp_r & ~dsr[`OR1200_DU_DSR_TE]); +`else +assign du_hwbkpt =3D 1'b0; +`endif + +// Hold du_hwbkpt if ex_freeze is active in= order to cause trap exception +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + du_hwbkpt_hold <=3D 1'b0; + else if (du_hwbkpt & ex_freeze) + du_hwbkpt_hold <=3D 1'b1; + else if (!ex_freeze) + du_hwbkpt_hold <=3D 1'b0; + +`ifdef OR1200_DU_TB_IMPLEMENTED +// +// Simple trace buffer +// (right now hardcoded for Xilinx Virtex F= PGAs) +// +// Stores last 256 instruction addresses, i= nstruction +// machine words and ALU results +// + +// +// Trace buffer write enable +// +assign tb_enw =3D ~ex_freeze & ~((ex_insn[31:26] =3D=3D `OR1200_OR32_NOP) & ex_insn[16]); + +// +// Trace buffer write address pointer +// +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + tb_wadr <=3D 8'h00; + else if (tb_enw) + tb_wadr <=3D tb_wadr + 8'd1; + +// +// Free running counter (time stamp) +// +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst =3D=3D `OR1200_RST_VALUE) + tb_timstmp <=3D 32'h00000000; + else if (!dbg_bp_r) + tb_timstmp <=3D tb_timstmp + 32'd1; + +// +// Trace buffer RAMs +// + +or1200_dpram_256x32 tbia_ram( + .clk_a(clk), + .rst_a(1'b0), + .addr_a(spr_addr[7:0]), + .ce_a(1'b1), + .oe_a(1'b1), + .do_a(tbia_dat_o), + + .clk_b(clk), + .rst_b(1'b0), + .addr_b(tb_wadr), + .di_b(spr_dat_npc), + .ce_b(1'b1), + .we_b(tb_enw) + +); + +or1200_dpram_256x32 tbim_ram( + .clk_a(clk), + .rst_a(1'b0), + .addr_a(spr_addr[7:0]), + .ce_a(1'b1), + .oe_a(1'b1), + .do_a(tbim_dat_o), + = + .clk_b(clk), + .rst_b(1'b0), + .addr_b(tb_wadr), + .di_b(ex_insn), + .ce_b(1'b1), + .we_b(tb_enw) +); + +or1200_dpram_256x32 tbar_ram( + .clk_a(clk), + .rst_a(1'b0), + .addr_a(spr_addr[7:0]), + .ce_a(1'b1), + .oe_a(1'b1), + .do_a(tbar_dat_o), + = + .clk_b(clk), + .rst_b(1'b0), + .addr_b(tb_wadr), + .di_b(rf_dataw), + .ce_b(1'b1), + .we_b(tb_enw) +); + +or1200_dpram_256x32 tbts_ram( + .clk_a(clk), + .rst_a(1'b0), + .addr_a(spr_addr[7:0]), + .ce_a(1'b1), + .oe_a(1'b1), + .do_a(tbts_dat_o), + + .clk_b(clk), + .rst_b(1'b0), + .addr_b(tb_wadr), + .di_b(tb_timstmp), + .ce_b(1'b1), + .we_b(tb_enw) +); + +`else + +assign tbia_dat_o =3D 32'h0000_0000<= /span>; +assign tbim_dat_o =3D 32'h0000_0000<= /span>; +assign tbar_dat_o =3D 32'h0000_0000<= /span>; +assign tbts_dat_o =3D 32'h0000_0000<= /span>; + +`endif // OR1200_DU_TB_IMPLEMENTED + +`else // OR1200_DU_IMPLEMENTED + +// +// When DU is not implemented, drive all ou= tputs as would when DU is disabled +// +assign dbg_bp_o =3D 1'b0; +assign du_dsr =3D {`OR1200_DU_DSR_WI= DTH{1'b0}}; +assign du_dmr1 =3D {25{1'b0}}; +assign du_hwbkpt =3D 1'b0; + +// +// Read DU registers +// +`ifdef OR1200_DU_READREGS +assign spr_dat_o =3D 32'h0000_0000= span>; +`ifdef OR1200_DU_UNUSED_ZERO +`endif +`endif + +`endif + +endmodule +
+-------------------------------------------= ------------------------------------- +-- light52_muldiv.vhdl -- Simple multiplier= /divider module. +-------------------------------------------= ------------------------------------- +-- The 8051 mul and div instructions are bo= th unsigned and operands are 8 bit. +-- +-- This module implements the division as a= sequential state machine which takes +-- 8 cycles to complete. +-- The multiplier can be implemented as seq= uential or as combinational, in which +-- case it will use a DSP block in those ar= chitectures that support it. +-- No attempt has been made to make this mo= dule generic or reusable. +-- +-- If you want a combinational multiplier b= ut don't want to waste a DSP block +-- in this module, you need to modify this = file adding whatever synthesis +-- pragmas your tool of choice needs. +-- +-- Note that unlike the division state mach= ine, the combinational product logic +-- is always operating: when SEQUENTIAL_MUL= TIPLIER=3Dtrue, prod_out equals +-- data_a * data_b with a latency of 1 cloc= k cycle, and mul_ready is hardwired +-- to '1'. +-- +-- FIXME explain division algorithm. +-------------------------------------------= ------------------------------------- +-- GENERICS: +-- +-- SEQUENTIAL_MULTIPLIER -- Sequenti= al vs. combinational multiplier. +-- When true, a sequential implementation = will be used for the multiplier, +-- which will usually save a lot of logic = or a dedicated multiplier. +-- When false, a combinational registered = multiplier will be used. +-- +-------------------------------------------= ------------------------------------- +-- INTERFACE SIGNALS: +-- +-- clk : Clock, active rising ed= ge. +-- reset : Synchronous reset. Clea= rs only the control registers not +-- visible to the programm= er -- not the output registers. +-- +-- data_a : Numerator input, should= be connected to the ACC register. +-- data_b : Denominator input, shou= ld be connected to the B register. +-- start : Assert for 1 cycle to s= tart the division state machine +-- (and the product if SEQ= UENTIAL_MULTIPLIER=3Dtrue); +-- +-- prod_out : Product output, valid o= nly when mul_ready=3D'1'. +-- quot_out : Quotient output, valid = only when div_ready=3D'1'. +-- rem_out : Remainder output, valid= only when div_ready=3D'1'. +-- div_ov_out : Division overflow flag,= valid only when div_ready=3D'1'. +-- mul_ov_out : Product overflow flag, = valid only when mul_ready=3D'1'. +-- +-- mul_ready : Asserted permanently if= SEQUENTIAL_MULTIPLIER=3Dfalse. +-- div_ready : Deasserted the cycle af= ter start is asserted. +-- Asserted when the divis= ion has completed. +-- +-------------------------------------------= ------------------------------------- +-- Copyright (C) 2012 Jose A. Ruiz +-- = +-- This source file may be used and distrib= uted without +-- restriction provided that this copyright= statement is not +-- removed from the file and that any deriv= ative work contains +-- the original copyright notice and the as= sociated disclaimer. +-- = +-- This source file is free software; you c= an redistribute it +-- and/or modify it under the terms of the = GNU Lesser General +-- Public License as published by the Free = Software Foundation; +-- either version 2.1 of the License, or (a= t your option) any +-- later version. = +-- = +-- This source is distributed in the hope t= hat it will be +-- useful, but WITHOUT ANY WARRANTY; withou= t even the implied +-- warranty of MERCHANTABILITY or FITNESS F= OR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Pub= lic License for more +-- details. = +-- = +-- You should have received a copy of the G= NU Lesser General +-- Public License along with this source; i= f not, download it +-- from http://www.opencores.org/lgpl.shtml= +-------------------------------------------= ------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.light52_pkg.all; +use work.light52_ucode_pkg+ + diff --git a/autotests/input/syntax/vhdl/results/light52_tb.vhdl.reference.= html b/autotests/input/syntax/vhdl/results/light52_tb.vhdl.reference.html new file mode 100644 index 0000000..b10b1d3 --- /dev/null +++ b/autotests/input/syntax/vhdl/results/light52_tb.vhdl.reference.html @@ -0,0 +1,196 @@ + + + + + + +.all; + +entity light52_muldiv is + generic ( + SEQUENTIAL_MULTIPLIER : boolean := =3D false + ); + port( + clk : i= n std_logic; + reset : i= n std_logic; + = + data_a : i= n t_byte; + data_b : i= n t_byte; + start : i= n std_logic; + = + prod_out : o= ut t_word; + quot_out : o= ut t_byte; + rem_out : o= ut t_byte; + div_ov_out : o= ut std_logic; + mul_ov_out : o= ut std_logic; + = + mul_ready : o= ut std_logic; + div_ready : o= ut std_logic + ); +end entity light52_muldiv; + +architecture sequential of light52_muldiv is + +signal bit_ctr : integer= range 0 to 8; + +signal b_shift_reg : t_word; + +signal den_ge_256 : std_logic ; +signal num_ge_den : std_logic; +signal sub_num : std_logic; + +signal denominator : t_byte; +signal rem_reg : t_byte; +signal quot_reg : t_byte; +signal prod_reg : t_word; +signal ready : std_logic; + +signal load_regs : std_logic; + +begin + +-- Control logic --------------------------= ------------------------------------- + +control_counter: +process(clk) +begin + if clk'event and clk=3D<= /span>'1' then + if reset=3D'1' = then + bit_ctr <=3D 8; + else + if load_regs=3D'1' then + bit_ctr <=3D0 ; + elsif bit_ctr/=3D 8 then + bit_ctr <=3D bit_= ctr + = 1; + end if; + end if; + end if; +end process control_counter; + +-- Internal signal ready is asserted after = 8 cycles. +-- The sequential multiplier will use this = signal too, IF it takes 8 cycles. + +ready <=3D '1' when bit_ctr >= =3D 8 else '0'; + + +---- Divider logic ------------------------= ------------------------------------- + +-- What we do is a simple base-2 'shift-and= -subtract' algorithm that takes +-- 8 cycles to complete. We can get away wi= th this because we deal with unsigned +-- numbers only. + +divider_registers: +process(clk) +begin + if clk'event and clk=3D<= /span>'1' then + -- denominator shift register + if load_regs=3D'1' <= b>then + b_shift_reg <=3D"0" & data_b & "0000000"; + -- Division overflow can be det= ermined upon loading B reg data. + -- OV will be raised only on di= v-by-zero. + if data_b=3DX"00&q= uot; then + div_ov_out <=3D <= span style=3D'color:#b08000;'>'1'; + else + div_ov_out <=3D <= span style=3D'color:#b08000;'>'0'; + end if; + else + b_shift_reg <=3D"0" & b_shift_reg(b_shift_reg'hig= h downto 1); + end if; + = + -- numerator register + if load_regs=3D'1' <= b>then = + rem_reg <=3D data_a; + elsif bit_ctr/=3D8 <= b>and sub_num=3D'1' then = + rem_reg <=3D rem_reg = - denominator; + end if; + + --- quotient register + if load_regs=3D'1' <= b>then + quot_reg <=3D (others =3D&g= t; '0'); + elsif bit_ctr/=3D8 <= b>then + quot_reg <=3D quot_re= g(quot_reg'high-1 downto 0) & sub_num; + end if; + = + load_regs <=3D start; + end if; +end process divider_registers; + +denominator <=3D b_shift_reg(7 downto= span> 0); + +-- The 16-bit comparison between b_shift_re= g (denominator) and the zero-extended +-- rem_reg (numerator) can be simplified by= splitting it in 2: +-- If the shifted denominator high byte is = not zero, it is >=3D256... +den_ge_256 <=3D '1' when b_shift_reg(15 downto 8) /=3D X"00" else '0'; +-- ...otherwise we need to compare the low = bytes. +num_ge_den <=3D '1' when rem_reg >=3D denominator else '0'; +sub_num <=3D '1' when den_ge_256= =3D'0' and num_ge_den=3D'1'= span> else '0'; + + +quot_out <=3D quot_reg; +prod_out <=3D prod_reg; +rem_out <=3D rem_reg; + +div_ready <=3D ready; + +---- Multiplier logic ---------------------= ------------------------------------- + +---- Combinational multiplier -------------= ---------------- +multiplier_combinational: +if not SEQUENTIAL_MULTIPLIER generate + +registered_combinational_multiplier: +process(clk) +begin + if clk'event and clk=3D<= /span>'1' then + prod_reg <=3D data_a* data_b; = -- t_byte is unsigned + end if; +end process registered_combin= ational_multiplier; + +-- The multiplier output is valid in the cy= cle after the operands are loaded, +-- so by the time MUL is executed it's alre= ady done. +mul_ready <=3D '1'; + +mul_ov_out <=3D '1' when prod_reg(15 downto 8)/=3DX"00" else '0'; +prod_out <=3D prod_reg; + +end generate multiplier_combinational; + +---- Sequential multiplier ----------------= ---------------- +multiplier_sequential: +if SEQUENTIAL_MULTIPLIER generate + +assert false +report "Sequential multiplier i= mplementation not done yet."&= ; + " Use combinational implementat= ion." +severity failure; + +end generate multiplier_sequential; + +end sequential; +
+-------------------------------------------= ------------------------------------- +-- light52_tb.vhdl -- +-------------------------------------------= ------------------------------------- +-- This test bench simulates the execution = of some program (whose object code +-- is in package obj_code_pkg, in the form = of a memory init constant) and logs +-- the execution to a text file called 'hw_= sim_log.txt' (light52_tb_pkg.vhdl). +-- +-- This test bench does no actual tests on = the core. Instead, the simulation log +-- is meant to be matched against the simul= ation log produced by running the +-- same program on the software simulator B= 51 (also included with this project). +-- +-- This will catch errors in the implementa= tion of the CPU if the simulated +-- program has anough coverage -- the opcod= e tester is meant to cover all CPU +-- opcodes in many (not all) of their corne= r cases. +-- This scheme will not help in catching er= rors in the peripheral modules, +-- mainly because the current version of B5= 1 does not simulate them. +-- +-------------------------------------------= ------------------------------------- +-- Copyright (C) 2012 Jose A. Ruiz +-- = +-- This source file may be used and distrib= uted without +-- restriction provided that this copyright= statement is not +-- removed from the file and that any deriv= ative work contains +-- the original copyright notice and the as= sociated disclaimer. +-- = +-- This source file is free software; you c= an redistribute it +-- and/or modify it under the terms of the = GNU Lesser General +-- Public License as published by the Free = Software Foundation; +-- either version 2.1 of the License, or (a= t your option) any +-- later version. = +-- = +-- This source is distributed in the hope t= hat it will be +-- useful, but WITHOUT ANY WARRANTY; withou= t even the implied +-- warranty of MERCHANTABILITY or FITNESS F= OR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Pub= lic License for more +-- details. = +-- = +-- You should have received a copy of the G= NU Lesser General +-- Public License along with this source; i= f not, download it +-- from http://www.opencores.org/lgpl.shtml= +-------------------------------------------= ------------------------------------- + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned+ + diff --git a/autotests/src/katesyntaxtest.cpp b/autotests/src/katesyntaxtes= t.cpp new file mode 100644 index 0000000..c99a5c6 --- /dev/null +++ b/autotests/src/katesyntaxtest.cpp @@ -0,0 +1,129 @@ +/* This file is part of the Kate project. + * + * Copyright (C) 2013 Dominik Haumann.all; +use std.textio.all; + +use work.light52_pkg.all; +use work.obj_code_pkg.all; +use work.light52_tb_pkg.all; +use work.txt_util.all; + +entity light52_tb is +generic (BCD : boolean :=3D true); +end; + + +architecture testbench of light52_tb is + +-------------------------------------------= ------------------------------------- +-- Simulation parameters +-- FIXME these should be in parameter packa= ge + +-- Simulated clock period is the same as th= e usual target, the DE-1 board +constant T : time :=3D 20 ns; -- 50MHz= span> +constant SIMULATION_LENGTH : integer :=3D 400000; + +-------------------------------------------= ------------------------------------- +-- MPU interface + +signal clk : std_logic :=3D '0'; +signal reset : std_logic :=3D '1'; + +signal p0_out : std_logic_vect= or(7 downto 0); +signal p1_out : std_logic_vect= or(7 downto 0); +signal p2_in : std_logic_vect= or(7 downto 0); +signal p3_in : std_logic_vect= or(7 downto 0); + +signal external_irq : std_logic_vect= or(7 downto 0); + +signal txd, rxd : std_logic; + +-------------------------------------------= ------------------------------------- +-- Logging signals & simulation control= + +-- Asserted high to disable the clock and t= erminate the simulation. +signal done : std_logic :=3D '0'; + +-- Log file +file log_file: TEXT open write_mode is "hw_sim_log.txt"; +-- Console output log file +file con_file: TEXT open write_mode is "hw_sim_console_log.txt"; +-- Info record needed by the logging fuctio= ns +signal log_info : t_log_info; + +begin + +---- UUT instantiation --------------------= ------------------------------------- + +uut: entity work.light52_mcu + generic map ( + IMPLEMENT_BCD_INSTRUCTIONS =3D><= /span> BCD, + CODE_ROM_SIZE =3D> wor= k.obj_code_pkg.XCODE_SIZE, + XDATA_RAM_SIZE =3D> wor= k.obj_code_pkg.XDATA_SIZE, + OBJ_CODE =3D> wor= k.obj_code_pkg.object_code + ) + port map ( + clk =3D> clk<= span style=3D'color:#006e28;'>, + reset =3D> rese= t, + = + txd =3D> txd<= span style=3D'color:#006e28;'>, + rxd =3D> rxd<= span style=3D'color:#006e28;'>, + = + external_irq =3D> exte= rnal_irq, + = + p0_out =3D> p0_o= ut, + p1_out =3D> p1_o= ut, + p2_in =3D> p2_i= n, + p3_in =3D> p3_in + ); + = + -- UART is looped back in the test benc= h. + rxd <=3D txd; + = + -- I/O ports are looped back and otherw= ise unused. + p2_in <=3D p0_out; + p3_in <=3D p1_out; + = + -- External IRQ inputs are tied to port= P1 for test purposes + external_irq <=3D p1_out; + + ---- Master clock: free running clock u= sed as main module clock ------------ + run_master_clock: + process(done, clk) + begin + if done =3D '0' then + clk <=3D not c= lk after T/2; + end if; + end process run_master_cl= ock; + + + ---- Main simulation process: reset MCU= and wait for fixed period ---------- + + drive_uut: + process + begin + -- Leave reset asserted for a few c= lock cycles... + reset <=3D '1'; + wait for T*4; + reset <=3D '0'; + = + -- ...and wait for the test to hit = a termination condition (evaluated by + -- function log_cpu_activity) or to= just timeout. + wait for T*SIMULATION= _LENGTH; + + -- If we arrive here, the simulatio= n timed out (termination conditions + -- trigger a failed assertion). + -- So print a timeout message and q= uit. + print("TB timed out."); + done <=3D '1'; + wait; + = + end process drive_uut; + + + -- Logging process: launch logger funct= ions -------------------------------- + log_execution: + process + begin + -- Log cpu activity until done=3D'1= '. + log_cpu_activity(clk, reset<= span style=3D'color:#006e28;'>, done,= "/uut", + log_info, w= ork.obj_code_pkg.XCODE_SIZE, "log_info", = + X"0000"<= /span>, log_file, con_file); + = + -- Flush console log file when fini= shed. + log_flush_console(log_info, = con_file); + = + wait; + end process log_execution; + +end architecture testbench; +