OpenCores
URL https://opencores.org/ocsvn/xgate/xgate/trunk

Subversion Repositories xgate

[/] [xgate/] [trunk/] [rtl/] [verilog/] [xgate_risc.v] - Blame information for rev 72

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rehayes
////////////////////////////////////////////////////////////////////////////////
2
//
3
//  XGATE Coprocessor - XGATE RISC Processor Core
4
//
5
//  Author: Bob Hayes
6
//          rehayes@opencores.org
7
//
8
//  Downloaded from: http://www.opencores.org/projects/xgate.....
9
//
10
////////////////////////////////////////////////////////////////////////////////
11
// Copyright (c) 2009, Robert Hayes
12
//
13
// This source file is free software: you can redistribute it and/or modify
14
// it under the terms of the GNU Lesser General Public License as published
15
// by the Free Software Foundation, either version 3 of the License, or
16
// (at your option) any later version.
17
//
18
// Supplemental terms.
19
//     * Redistributions of source code must retain the above copyright
20
//       notice, this list of conditions and the following disclaimer.
21
//     * Neither the name of the <organization> nor the
22
//       names of its contributors may be used to endorse or promote products
23
//       derived from this software without specific prior written permission.
24
//
25
// THIS SOFTWARE IS PROVIDED BY Robert Hayes ''AS IS'' AND ANY
26
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28
// DISCLAIMED. IN NO EVENT SHALL Robert Hayes BE LIABLE FOR ANY
29
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
//
36
// You should have received a copy of the GNU General Public License
37
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
38
////////////////////////////////////////////////////////////////////////////////
39
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
40
 
41
module xgate_risc #(parameter MAX_CHANNEL = 127)    // Max XGATE Interrupt Channel Number
42
 (
43
  output reg [15:0] xgr1,
44
  output reg [15:0] xgr2,
45
  output reg [15:0] xgr3,
46
  output reg [15:0] xgr4,
47
  output reg [15:0] xgr5,
48
  output reg [15:0] xgr6,
49
  output reg [15:0] xgr7,
50
  output     [15:0] xgate_address,
51
  output     [15:0] write_mem_data,   // Data for Memory write
52 34 rehayes
  output            mem_access,       // 
53 2 rehayes
  output            write_mem_strb_l, // Strobe for writing low data byte
54
  output            write_mem_strb_h, // Strobe for writing high data bye
55
  output reg                 zero_flag,
56
  output reg                 negative_flag,
57
  output reg                 carry_flag,
58
  output reg                 overflow_flag,
59
  output reg          [ 6:0] xgchid,
60 72 rehayes
  output reg         [127:1] xgif_status,   // XGATE Interrupt Flag
61 12 rehayes
  output                     xg_sw_irq,     // Xgate Software interrupt
62 2 rehayes
  output              [ 7:0] host_semap,    // Semaphore status for host
63 12 rehayes
  output reg                 debug_active,  // Latch to control debug mode in the RISC state machine
64 53 rehayes
  output                     debug_ack,     // Clear debug register
65
  output                     single_step,   // Pulse to trigger a single instruction execution in debug mode
66 2 rehayes
 
67
 
68
  input      [15:0] read_mem_data,
69
  input      [15:0] perif_data,
70
  input             risc_clk,
71
  input             async_rst_b,
72 5 rehayes
  input             mem_req_ack,    // Memory Bus available - data good
73 53 rehayes
  input             ss_mem_ack,     // WISHBONE Bus has granted single step memory access
74 2 rehayes
  input             xge,            // XGATE Module Enable
75 31 rehayes
  input             debug_mode_i,   // Force RISC core into debug mode
76 53 rehayes
  input             xgdbg_set,      // Enter XGATE Debug Mode, pulse
77 15 rehayes
  input             xgdbg_clear,    // Leave XGATE Debug Mode
78 2 rehayes
  input             xgss,           // XGATE Single Step
79
  input      [15:1] xgvbr,          // XGATE vector Base Address Register
80
  input      [ 6:0] int_req,        // Encoded interrupt request
81 12 rehayes
  input             xgie,           // XGATE Interrupt Enable
82
  input             brk_irq_ena,    // Enable BRK instruction to generate interrupt
83 17 rehayes
  input             write_xgchid,   // Write Strobe for XGCHID register
84 2 rehayes
  input             write_xgsem,    // Write Strobe for XGSEM register
85
  input             write_xgccr,    // Write Strobe for XGATE Condition Code Register
86 41 rehayes
  input      [ 1:0] write_xgpc,     // Write Strobe for XGATE Program Counter
87
  input      [ 1:0] write_xgr7,     // Write Strobe for XGATE Data Register R7
88
  input      [ 1:0] write_xgr6,     // Write Strobe for XGATE Data Register R6
89
  input      [ 1:0] write_xgr5,     // Write Strobe for XGATE Data Register R5
90
  input      [ 1:0] write_xgr4,     // Write Strobe for XGATE Data Register R4
91
  input      [ 1:0] write_xgr3,     // Write Strobe for XGATE Data Register R3
92
  input      [ 1:0] write_xgr2,     // Write Strobe for XGATE Data Register R2
93
  input      [ 1:0] write_xgr1,     // Write Strobe for XGATE Data Register R1
94 12 rehayes
  input             xgsweif_c,      // Clear Software Flag
95 2 rehayes
  input             clear_xgif_7,   // Strobe for decode to clear interrupt flag bank 7
96
  input             clear_xgif_6,   // Strobe for decode to clear interrupt flag bank 6
97
  input             clear_xgif_5,   // Strobe for decode to clear interrupt flag bank 5
98
  input             clear_xgif_4,   // Strobe for decode to clear interrupt flag bank 4
99
  input             clear_xgif_3,   // Strobe for decode to clear interrupt flag bank 3
100
  input             clear_xgif_2,   // Strobe for decode to clear interrupt flag bank 2
101
  input             clear_xgif_1,   // Strobe for decode to clear interrupt flag bank 1
102
  input             clear_xgif_0,   // Strobe for decode to clear interrupt flag bank 0
103
  input      [15:0] clear_xgif_data // Data for decode to clear interrupt flag
104
);
105
 
106 26 rehayes
  integer j;     // Loop counters for decode of XGATE Interrupt Register
107 2 rehayes
  integer k;     // Loop counter for Bit Field Insert decode
108 26 rehayes
  integer bfi, bfii;   // Loop counter for Bit Field Insert function
109 2 rehayes
 
110
  // State machine sequence
111 5 rehayes
  parameter [3:0]      //synopsys enum state_info
112
       IDLE    = 4'b0000,      // waiting for interrupt
113
       CONT    = 4'b0001,      // Instruction processing state, first state
114 12 rehayes
       S_STALL = 4'b0010,      // Simple Stall while updating PC after change of flow
115 40 rehayes
       W_STORE = 4'b1101,      // Stall while doing memory word write access
116
       W_LOAD  = 4'b0011,      // Stall while doing memory word read access
117
       B_LOAD  = 4'b0100,      // Stall while doing memory byte read access
118 12 rehayes
       BREAK   = 4'b0101,      // Stop in this state after BRK instruction
119
       BREAK_2 = 4'b0110,      // Advance PC after Single Step command
120
       LD_INST = 4'b0111,      // Load Instruction in Debug mode
121
       DEBUG   = 4'b1000,      // Stop in this state while waiting for debug commands
122
       BOOT_1  = 4'b1001,      //
123
       BOOT_2  = 4'b1010,      //
124 17 rehayes
       BOOT_3  = 4'b1011,      //
125
       CHG_CHID = 4'b1100;
126 12 rehayes
 
127
 
128 2 rehayes
  // Semaphore states
129
  parameter [1:0] NO_LOCK = 2'b00,
130 12 rehayes
                  RISC_LOCK = 2'b10,
131
                  HOST_LOCK = 2'b11;
132
 
133
 
134
  reg  [ 3:0] cpu_state;         // State register for instruction processing
135 5 rehayes
  reg  [ 3:0] next_cpu_state;    // Pseudo Register,
136 64 rehayes
  wire        stm_auto_advance;  // State Machine increment without wait state holdoff
137 2 rehayes
  reg         load_next_inst;    // Pseudo Register,
138 12 rehayes
  reg  [15:0] program_counter;   // Program Counter register
139 40 rehayes
  wire [15:0] pc_sum;            // Program Counter Adder
140
  reg  [15:0] pc_incr_mux;       // Pseudo Register, mux to select the Program Counter Increment value
141
  reg  [15:0] next_pc;           // Pseudo Register
142
  wire [15:0] jump_offset;       // Address offset to be added to pc on conditional branch instruction
143
  wire [15:0] bra_offset;        // Address offset to be added to pc on branch always instruction
144 2 rehayes
  reg  [15:0] alu_result;        // Pseudo Register,
145 12 rehayes
  reg  [15:0] op_code;           // Register for instruction being executed
146 2 rehayes
  reg         ena_rd_low_byte;   // Pseudo Register,
147
  reg         ena_rd_high_byte;  // Pseudo Register,
148
 
149 12 rehayes
  reg         data_access;    // Pseudo Register, RAM access in proccess
150
  reg         data_write;     // Pseudo Register, RAM access is write operation
151
  reg         data_word_op;   // Pseudo Register, RAM access operation is 16 bits(word)
152
  reg  [15:0] data_address;   // Pseudo Register, Address for RAM data read or write
153
  reg  [15:0] load_data;      // Data captured from WISHBONE Master bus for Load instructions
154
 
155
  reg  [ 6:0] set_irq_flag;   // Pseudo Register, pulse for setting irq output register
156
 
157 2 rehayes
  reg         next_zero;      // Pseudo Register,
158
  reg         next_negative;  // Pseudo Register,
159
  reg         next_carry;     // Pseudo Register,
160
  reg         next_overflow;  // Pseudo Register,
161 17 rehayes
 
162 12 rehayes
  reg         op_code_error;  // Pseudo Register,
163
  reg         software_error; // OP Code error, Address Error, BRK Error
164
  wire        addr_error;     // Decode Addressing error
165 2 rehayes
 
166
  reg         set_semaph;     // Pseudo Register,
167
  reg         clear_semaph;   // Pseudo Register,
168
  reg  [ 2:0] semaph_risc;    // Pseudo Register,
169
  reg  [ 7:0] semap_risc_bit; // Pseudo Register,
170
  wire [ 7:0] risc_semap;     // Semaphore status bit for RISC
171
  wire        semaph_stat;    // Return Status of Semaphore bit
172 12 rehayes
 
173 2 rehayes
  reg  [15:0] rd_data;        // Pseudo Register,
174
  reg  [15:0] rs1_data;       // Pseudo Register,
175
  reg  [15:0] rs2_data;       // Pseudo Register,
176 12 rehayes
 
177 2 rehayes
  wire [ 2:0] wrt_reg_sel;
178 12 rehayes
  reg         sel_rd_field;   // Pseudo Register,
179
  reg         wrt_sel_xgr1;   // Pseudo Register,
180
  reg         wrt_sel_xgr2;   // Pseudo Register,
181
  reg         wrt_sel_xgr3;   // Pseudo Register,
182
  reg         wrt_sel_xgr4;   // Pseudo Register,
183
  reg         wrt_sel_xgr5;   // Pseudo Register,
184
  reg         wrt_sel_xgr6;   // Pseudo Register,
185
  reg         wrt_sel_xgr7;   // Pseudo Register,
186
 
187 72 rehayes
  reg [127:1] xgif_d;
188 12 rehayes
 
189 2 rehayes
  reg  [15:0] shift_in;
190
  wire [15:0] shift_out;
191
  wire        shift_rollover;
192
  reg         shift_left;
193
  reg  [ 4:0] shift_ammount;
194
  reg  [15:0] shift_filler;
195 53 rehayes
  reg  [15:0] bf_mux_mask;   // Mask for controlling mux's in Bit Field Insert Instructions
196 12 rehayes
 
197 59 rehayes
  wire        start_thread;  // Signal to pop RISC core out of IDLE State
198 2 rehayes
 
199 12 rehayes
  wire        cpu_is_idle;   // Processor is in the IDLE state
200
  wire        perif_wrt_ena; // Enable for Salve writes to CPU registers
201
 
202
  reg         xgss_edge;     // Flop for edge detection
203
  reg         brk_set_dbg;   // Pulse to set debug_active from instruction decoder
204 15 rehayes
  reg         cmd_change_pc; // Debug write to PC register
205 53 rehayes
  reg         debug_edge;    // Reg for edge detection
206 12 rehayes
 
207 64 rehayes
  reg         cmd_dbg;
208
 
209 31 rehayes
  reg  [ 1:0] chid_sm_ns;    // Pseudo Register for State Machine next state logic,
210 17 rehayes
  reg  [ 1:0] chid_sm;       //
211
  wire        chid_goto_idle; //
212 12 rehayes
 
213 17 rehayes
  // Debug states for change CHID
214
  parameter [1:0] CHID_IDLE = 2'b00,
215
                  CHID_TEST = 2'b10,
216
                  CHID_WAIT = 2'b11;
217
 
218 64 rehayes
 
219 40 rehayes
  assign jump_offset = {{6{op_code[8]}}, op_code[8:0], 1'b0};
220
  assign bra_offset  = {{5{op_code[9]}}, op_code[9:0], 1'b0};
221
  assign pc_sum      = program_counter + pc_incr_mux;
222 17 rehayes
 
223 2 rehayes
  assign xgate_address = data_access ? data_address : program_counter;
224 34 rehayes
 
225 59 rehayes
  //assign mem_access = data_access || load_next_inst || start_thread;
226 53 rehayes
  assign mem_access = data_access || load_next_inst || (cpu_state == CONT) ||
227 59 rehayes
                     (cpu_state == BREAK_2)  || start_thread;
228 17 rehayes
 
229 12 rehayes
  // Generate an address for an op code fetch from an odd address or a word Load/Store from/to an odd address.
230
  assign addr_error = xgate_address[0] && (load_next_inst || (data_access && data_word_op));
231
 
232 2 rehayes
  assign write_mem_strb_l = data_access && data_write && (data_word_op || !data_address[0]);
233
  assign write_mem_strb_h = data_access && data_write && (data_word_op ||  data_address[0]);
234
  assign write_mem_data   = (write_mem_strb_l || write_mem_strb_h) ? rd_data : 16'b0;
235 12 rehayes
 
236 17 rehayes
  assign start_thread = xge && (|int_req) && !debug_active;
237 12 rehayes
 
238
  assign cpu_is_idle = (cpu_state == IDLE);
239 15 rehayes
  assign perif_wrt_ena = (cpu_is_idle && ~xge) || debug_active;
240 12 rehayes
 
241 2 rehayes
  // Decode register select for RD and RS
242
  always @*
243
    begin
244 26 rehayes
      case (op_code[10:8]) // synopsys parallel_case
245 2 rehayes
        3'b001 : rd_data = xgr1;
246
        3'b010 : rd_data = xgr2;
247
        3'b011 : rd_data = xgr3;
248
        3'b100 : rd_data = xgr4;
249
        3'b101 : rd_data = xgr5;
250
        3'b110 : rd_data = xgr6;
251
        3'b111 : rd_data = xgr7;
252
        default : rd_data = 16'h0;  // XGR0 is always Zero
253
      endcase
254
    end
255
 
256 47 rehayes
  assign wrt_reg_sel = (cpu_state == BOOT_3) ? 3'b001 :
257
                       (sel_rd_field ? op_code[10:8] : op_code[4:2]);
258 2 rehayes
 
259
  // Decode register write select for eather RD or RI/RS2
260
  always @*
261
    begin
262 47 rehayes
      wrt_sel_xgr1 = (wrt_reg_sel == 3'b001) && mem_req_ack;
263
      wrt_sel_xgr2 = (wrt_reg_sel == 3'b010) && mem_req_ack;
264
      wrt_sel_xgr3 = (wrt_reg_sel == 3'b011) && mem_req_ack;
265
      wrt_sel_xgr4 = (wrt_reg_sel == 3'b100) && mem_req_ack;
266
      wrt_sel_xgr5 = (wrt_reg_sel == 3'b101) && mem_req_ack;
267
      wrt_sel_xgr6 = (wrt_reg_sel == 3'b110) && mem_req_ack;
268
      wrt_sel_xgr7 = (wrt_reg_sel == 3'b111) && mem_req_ack;
269 2 rehayes
    end
270
 
271
  // Decode register select for RS1 and RB
272
  always @*
273 26 rehayes
    case (op_code[7:5])  // synopsys parallel_case
274 2 rehayes
      3'b001 : rs1_data = xgr1;
275
      3'b010 : rs1_data = xgr2;
276
      3'b011 : rs1_data = xgr3;
277
      3'b100 : rs1_data = xgr4;
278
      3'b101 : rs1_data = xgr5;
279
      3'b110 : rs1_data = xgr6;
280
      3'b111 : rs1_data = xgr7;
281
      default : rs1_data = 16'h0;  // XGR0 is always Zero
282
    endcase
283
 
284
  // Decode register select for RS2 and RI
285
  always @*
286 26 rehayes
    case (op_code[4:2])  // synopsys parallel_case
287 2 rehayes
      3'b001 : rs2_data = xgr1;
288
      3'b010 : rs2_data = xgr2;
289
      3'b011 : rs2_data = xgr3;
290
      3'b100 : rs2_data = xgr4;
291
      3'b101 : rs2_data = xgr5;
292
      3'b110 : rs2_data = xgr6;
293
      3'b111 : rs2_data = xgr7;
294
      default : rs2_data = 16'h0;  // XGR0 is always Zero
295
    endcase
296
 
297
  // Decode mux select mask for Bit Field Insert Instructions
298
  always @*
299
    begin
300
      k = 0;
301
      while (k < 16)
302
        begin
303
          bf_mux_mask[k] = 1'b0;
304
          if ((k >= rs2_data[3:0]) && (k <= rs2_data[3:0] + rs2_data[7:4]))
305
            bf_mux_mask[k] = 1'b1;
306
          k = k + 1;
307
        end
308
    end
309
 
310 12 rehayes
  //  Software Error Interrupt Latch
311
  always @(posedge risc_clk or negedge async_rst_b)
312
    if ( !async_rst_b )
313
      software_error <= 1'b0;
314
    else
315 17 rehayes
      software_error <= addr_error || op_code_error ||
316 12 rehayes
                        (brk_set_dbg && brk_irq_ena) || (software_error && !xgsweif_c);
317 17 rehayes
 
318 12 rehayes
  assign xg_sw_irq = software_error && xgie;
319
 
320 64 rehayes
  //  Latch the need to go to debug state set by xgdb
321
  always @(posedge risc_clk or negedge async_rst_b)
322
    if ( !async_rst_b )
323
      begin
324
        cmd_dbg  <= 1'b0;
325
      end
326
    else
327
      begin
328
        cmd_dbg  <= !((cpu_state == LD_INST) || (cpu_state == DEBUG)) &&
329
                     (cmd_dbg || (xgdbg_set && mem_req_ack && (next_cpu_state == CONT)));
330
      end
331
 
332 12 rehayes
  //  Latch the debug state, set by eather xgdb or BRK instructions
333
  always @(posedge risc_clk or negedge async_rst_b)
334
    if ( !async_rst_b )
335 53 rehayes
      begin
336 64 rehayes
        debug_active  <= 1'b0;
337
        debug_edge    <= 0;
338 53 rehayes
      end
339 12 rehayes
    else
340 53 rehayes
      begin
341 64 rehayes
        debug_active  <= !xgdbg_clear && (cmd_dbg ||
342
                         brk_set_dbg || op_code_error || debug_active);
343
        debug_edge    <= debug_active;
344 53 rehayes
      end
345
 
346
  assign debug_ack = debug_active && !debug_edge; // Posedge of debug_active
347 12 rehayes
 
348
  //  Convert xgss (Single Step Pulse) to a one risc_clk wide pulse
349
  always @(posedge risc_clk or negedge async_rst_b)
350
    if ( !async_rst_b )
351
      xgss_edge  <= 1'b0;
352
    else
353
      xgss_edge  <= xgss;
354
 
355 53 rehayes
  assign single_step = (xgss && !xgss_edge) || (!debug_active && debug_edge);
356 12 rehayes
 
357 59 rehayes
  assign stm_auto_advance = (chid_sm != CHID_IDLE);
358 12 rehayes
 
359 2 rehayes
  //  CPU State Register
360
  always @(posedge risc_clk or negedge async_rst_b)
361
    if ( !async_rst_b )
362
      cpu_state  <= IDLE;
363
    else
364 59 rehayes
      cpu_state  <= (mem_req_ack || stm_auto_advance) ? next_cpu_state : cpu_state;
365 2 rehayes
 
366
  //  CPU Instruction Register
367
  always @(posedge risc_clk or negedge async_rst_b)
368
    if ( !async_rst_b )
369
      op_code  <= 16'h0000;
370
    else
371 5 rehayes
      op_code  <= (load_next_inst && mem_req_ack) ? read_mem_data : op_code;
372 12 rehayes
 
373 2 rehayes
  //  Active Channel Latch
374
  always @(posedge risc_clk or negedge async_rst_b)
375
    if ( !async_rst_b )
376
      xgchid  <= 7'b0;
377
    else
378 59 rehayes
      xgchid  <= (write_xgchid && debug_active) ? perif_data[6:0] : (cpu_is_idle ? int_req : xgchid);
379 2 rehayes
 
380 17 rehayes
  //  Channel Change Debug state machine register
381
  always @(posedge risc_clk or negedge async_rst_b)
382
    if ( !async_rst_b )
383
      chid_sm  <= CHID_IDLE;
384
    else
385
      chid_sm  <= chid_sm_ns;
386
 
387
  //  Channel Change Debug next state
388
  always @*
389 26 rehayes
    case (chid_sm)  // synopsys parallel_case
390 17 rehayes
      CHID_IDLE:
391
        if ( write_xgchid && debug_active )
392
          chid_sm_ns  = CHID_TEST;
393
      CHID_TEST:
394
        if ( !((cpu_state == IDLE) || (cpu_state == CHG_CHID)) && (|xgchid) )
395
          chid_sm_ns  = CHID_IDLE;
396
        else
397
          chid_sm_ns  = CHID_WAIT;
398
      CHID_WAIT:
399
        if ( (cpu_state == IDLE) || (cpu_state == CHG_CHID) )
400
          chid_sm_ns  = CHID_IDLE;
401
        else
402
          chid_sm_ns  = CHID_WAIT;
403
      default : chid_sm_ns  = CHID_IDLE;
404
    endcase
405
 
406
  assign chid_goto_idle = (chid_sm == CHID_WAIT);
407
 
408 2 rehayes
  //  CPU Read Data Buffer Register
409
  always @(posedge risc_clk or negedge async_rst_b)
410
    if ( !async_rst_b )
411
      load_data  <= 16'h0000;
412
    else
413 5 rehayes
      load_data  <= (data_access && !data_write && mem_req_ack) ? read_mem_data : load_data;
414 2 rehayes
 
415
  //  Program Counter Register
416
  always @(posedge risc_clk or negedge async_rst_b)
417
    if ( !async_rst_b )
418
      program_counter  <= 16'h0000;
419
    else
420 41 rehayes
      program_counter  <= (|write_xgpc && perif_wrt_ena) ?
421
      {(write_xgpc[1] ? perif_data[15:8]: program_counter[15:8]),
422
       (write_xgpc[0] ? perif_data[ 7:0]: program_counter[ 7:0])} :
423
      (mem_req_ack ? next_pc : program_counter);
424 2 rehayes
 
425 15 rehayes
  //  Debug Change Program Counter Register
426
  always @(posedge risc_clk or negedge async_rst_b)
427
    if ( !async_rst_b )
428
      cmd_change_pc  <= 1'b0;
429
    else
430 53 rehayes
      cmd_change_pc  <= (|write_xgpc && perif_wrt_ena) || (cmd_change_pc && !mem_req_ack);
431 15 rehayes
 
432 2 rehayes
  //  ALU Flag Bits
433
  always @(posedge risc_clk or negedge async_rst_b)
434
    if ( !async_rst_b )
435
      begin
436
        carry_flag    <= 1'b0;
437
        overflow_flag <= 1'b0;
438
        zero_flag     <= 1'b0;
439
        negative_flag <= 1'b0;
440
      end
441
    else
442
      begin
443 12 rehayes
        carry_flag    <= (write_xgccr && perif_wrt_ena) ? perif_data[0] : (mem_req_ack ? next_carry : carry_flag);
444
        overflow_flag <= (write_xgccr && perif_wrt_ena) ? perif_data[1] : (mem_req_ack ? next_overflow : overflow_flag);
445
        zero_flag     <= (write_xgccr && perif_wrt_ena) ? perif_data[2] : (mem_req_ack ? next_zero : zero_flag);
446
        negative_flag <= (write_xgccr && perif_wrt_ena) ? perif_data[3] : (mem_req_ack ? next_negative : negative_flag);
447 2 rehayes
      end
448
 
449
  //  Interrupt Flag next value
450
  always @*
451 12 rehayes
    begin
452 31 rehayes
      xgif_d = 0;
453 72 rehayes
      j = 1;
454
      while (j <= MAX_CHANNEL)  // while loop sets irq bit and maintains previously set bits
455 12 rehayes
        begin
456 31 rehayes
         xgif_d[j]  = xgif_status[j] || (set_irq_flag == j);
457 12 rehayes
         j = j + 1;
458
        end
459 67 rehayes
      if (clear_xgif_0)
460 72 rehayes
        xgif_d[15: 1]  = ~clear_xgif_data & xgif_status[15: 1];
461 67 rehayes
      if (clear_xgif_1)
462
        xgif_d[31:16]  = ~clear_xgif_data & xgif_status[31:16];
463
      if (clear_xgif_2)
464
        xgif_d[47:32]  = ~clear_xgif_data & xgif_status[47:32];
465
      if (clear_xgif_3)
466
        xgif_d[63:48]  = ~clear_xgif_data & xgif_status[63:48];
467
      if (clear_xgif_4)
468
        xgif_d[79:64]  = ~clear_xgif_data & xgif_status[79:64];
469
      if (clear_xgif_5)
470
        xgif_d[95:80]  = ~clear_xgif_data & xgif_status[95:80];
471
      if (clear_xgif_6)
472
        xgif_d[111:96]  = ~clear_xgif_data & xgif_status[111:96];
473
      if (clear_xgif_7)
474
        xgif_d[127:112] = ~clear_xgif_data & xgif_status[127:112];
475 12 rehayes
    end
476 2 rehayes
 
477
  //  Interrupt Flag Registers
478
  always @(posedge risc_clk or negedge async_rst_b)
479
    if ( !async_rst_b )
480 31 rehayes
      xgif_status  <= 0;
481 2 rehayes
    else
482 31 rehayes
      xgif_status  <= xgif_d;
483 2 rehayes
 
484
 
485
  //  RISC Data Registers
486
  always @(posedge risc_clk or negedge async_rst_b)
487
    if ( !async_rst_b )
488
      begin
489
        xgr1 <= 16'b0;
490
        xgr2 <= 16'b0;
491
        xgr3 <= 16'b0;
492
        xgr4 <= 16'b0;
493
        xgr5 <= 16'b0;
494
        xgr6 <= 16'b0;
495
        xgr7 <= 16'b0;
496
      end
497
    else
498
      begin
499 41 rehayes
        xgr1 <= (|write_xgr1 && perif_wrt_ena) ?
500
                {(write_xgr1[1] ? perif_data[15:8]: xgr1[15:8]),
501
                 (write_xgr1[0] ? perif_data[ 7:0]: xgr1[ 7:0])} :
502 2 rehayes
                {((wrt_sel_xgr1 && ena_rd_high_byte) ? alu_result[15:8] : xgr1[15:8]),
503
                 ((wrt_sel_xgr1 && ena_rd_low_byte)  ? alu_result[ 7:0] : xgr1[ 7:0])};
504 41 rehayes
        xgr2 <= (|write_xgr2 && perif_wrt_ena) ?
505
                {(write_xgr2[1] ? perif_data[15:8]: xgr2[15:8]),
506
                 (write_xgr2[0] ? perif_data[ 7:0]: xgr2[ 7:0])} :
507 2 rehayes
                {((wrt_sel_xgr2 && ena_rd_high_byte) ? alu_result[15:8] : xgr2[15:8]),
508
                 ((wrt_sel_xgr2 && ena_rd_low_byte)  ? alu_result[ 7:0] : xgr2[ 7:0])};
509 41 rehayes
        xgr3 <= (|write_xgr3 && perif_wrt_ena) ?
510
                {(write_xgr3[1] ? perif_data[15:8]: xgr3[15:8]),
511
                 (write_xgr3[0] ? perif_data[ 7:0]: xgr3[ 7:0])} :
512 2 rehayes
                {((wrt_sel_xgr3 && ena_rd_high_byte) ? alu_result[15:8] : xgr3[15:8]),
513
                 ((wrt_sel_xgr3 && ena_rd_low_byte)  ? alu_result[ 7:0] : xgr3[ 7:0])};
514 41 rehayes
        xgr4 <= (|write_xgr4 && perif_wrt_ena) ?
515
                {(write_xgr4[1] ? perif_data[15:8]: xgr4[15:8]),
516
                 (write_xgr4[0] ? perif_data[ 7:0]: xgr4[ 7:0])} :
517 2 rehayes
                {((wrt_sel_xgr4 && ena_rd_high_byte) ? alu_result[15:8] : xgr4[15:8]),
518
                 ((wrt_sel_xgr4 && ena_rd_low_byte)  ? alu_result[ 7:0] : xgr4[ 7:0])};
519 41 rehayes
        xgr5 <= (|write_xgr5 && perif_wrt_ena) ?
520
                {(write_xgr5[1] ? perif_data[15:8]: xgr5[15:8]),
521
                 (write_xgr5[0] ? perif_data[ 7:0]: xgr5[ 7:0])} :
522 2 rehayes
                {((wrt_sel_xgr5 && ena_rd_high_byte) ? alu_result[15:8] : xgr5[15:8]),
523
                 ((wrt_sel_xgr5 && ena_rd_low_byte)  ? alu_result[ 7:0] : xgr5[ 7:0])};
524 41 rehayes
        xgr6 <= (|write_xgr6 && perif_wrt_ena) ?
525
                {(write_xgr6[1] ? perif_data[15:8]: xgr6[15:8]),
526
                 (write_xgr6[0] ? perif_data[ 7:0]: xgr6[ 7:0])} :
527 2 rehayes
                {((wrt_sel_xgr6 && ena_rd_high_byte) ? alu_result[15:8] : xgr6[15:8]),
528
                 ((wrt_sel_xgr6 && ena_rd_low_byte)  ? alu_result[ 7:0] : xgr6[ 7:0])};
529 41 rehayes
        xgr7 <= (|write_xgr7 && perif_wrt_ena) ?
530
                {(write_xgr7[1] ? perif_data[15:8]: xgr7[15:8]),
531
                 (write_xgr7[0] ? perif_data[ 7:0]: xgr7[ 7:0])} :
532 2 rehayes
                {((wrt_sel_xgr7 && ena_rd_high_byte) ? alu_result[15:8] : xgr7[15:8]),
533
                 ((wrt_sel_xgr7 && ena_rd_low_byte)  ? alu_result[ 7:0] : xgr7[ 7:0])};
534
      end
535
 
536
  // V Ñ Vector fetch: always an aligned word read, lasts for at least one RISC core cycle
537
  // P Ñ Program word fetch: always an aligned word read, lasts for at least one RISC core cycle
538
  // r Ñ 8-bit data read: lasts for at least one RISC core cycle
539
  // R Ñ 16-bit data read: lasts for at least one RISC core cycle
540
  // w Ñ 8-bit data write: lasts for at least one RISC core cycle
541
  // W Ñ 16-bit data write: lasts for at least one RISC core cycle
542
  // A Ñ Alignment cycle: no read or write, lasts for zero or one RISC core cycles
543
  // f Ñ Free cycle: no read or write, lasts for one RISC core cycles
544
  // Special Cases
545
  // PP/P Ñ Branch: PP if branch taken, P if not taken
546
 
547
  always @*
548
    begin
549
      ena_rd_low_byte  = 1'b0;
550
      ena_rd_high_byte = 1'b0;
551
 
552 64 rehayes
      next_cpu_state = (debug_active || cmd_dbg) ? LD_INST : CONT;
553 2 rehayes
      load_next_inst = 1'b1;
554 64 rehayes
      pc_incr_mux    = cmd_dbg ? 16'h0000: 16'h0002;  // Verilog Instruction order dependent
555 40 rehayes
      next_pc        = pc_sum;    // ""
556 2 rehayes
 
557
      next_zero      = zero_flag;
558
      next_negative  = negative_flag;
559
      next_carry     = carry_flag;
560
      next_overflow  = overflow_flag;
561
 
562 12 rehayes
      brk_set_dbg    = 1'b0;
563
      op_code_error  = 1'b0;
564
 
565 2 rehayes
      alu_result     = 16'h0000;
566
      sel_rd_field   = 1'b1;
567 12 rehayes
 
568 2 rehayes
      data_access    = 1'b0;
569
      data_word_op   = 1'b0;
570 12 rehayes
      data_write     = 1'b0;
571 2 rehayes
      data_address   = 16'h0000;
572
 
573
      shift_left     = 1'b0;
574
      shift_ammount  = 5'b0_0000;
575
      shift_filler   = 16'h0000;
576
      shift_in       = rd_data;
577 12 rehayes
 
578 2 rehayes
      set_irq_flag   = 7'b0;
579 12 rehayes
 
580 2 rehayes
      set_semaph    = 1'b0;
581
      clear_semaph  = 1'b0;
582
      semaph_risc   = 3'b0;
583
 
584
  casez ({cpu_state, op_code})
585
 
586
      {IDLE, 16'b????????????????} :
587
         begin
588
           next_cpu_state   = start_thread ? BOOT_1 : IDLE;
589 40 rehayes
           pc_incr_mux      = 16'h0000;
590
           next_pc          = pc_sum;
591 2 rehayes
           load_next_inst   = 1'b0;
592
         end
593
 
594 17 rehayes
      {CHG_CHID, 16'b????????????????} :
595
         begin
596
           if (!xge)
597
             next_cpu_state = IDLE;
598 53 rehayes
           else if (ss_mem_ack || !debug_active)
599 17 rehayes
             next_cpu_state = BOOT_1;
600
           else
601
             next_cpu_state = CHG_CHID;
602
 
603 40 rehayes
           pc_incr_mux      = 16'h0000;
604
           next_pc          = pc_sum;
605 17 rehayes
           load_next_inst   = 1'b0;
606
         end
607
 
608 2 rehayes
      // Output RAM address for Program Counter
609
      {BOOT_1, 16'b????????????????} :
610
         begin
611
           next_cpu_state   = BOOT_2;
612 40 rehayes
           pc_incr_mux      = 16'h0000;
613
           next_pc          = pc_sum;
614 2 rehayes
           load_next_inst   = 1'b0;
615
           data_access      = 1'b1;
616
           data_word_op     = 1'b1;
617
           data_address     = {xgvbr, 1'b0} + {7'b0, xgchid, 2'b0};
618
         end
619
 
620
      // Load PC value from data buffer register
621
      // Output RAM address for initial variable pointer
622
      {BOOT_2, 16'b????????????????} :
623
         begin
624
           next_cpu_state   = BOOT_3;
625
           next_pc          = load_data;
626
           load_next_inst   = 1'b0;
627
           data_access      = 1'b1;
628
           data_word_op     = 1'b1;
629
           data_address     = {xgvbr, 1'b0} + {7'b0, xgchid, 2'b0} + 2;
630
         end
631
 
632
      // Load R1 with initial variable pointer from data buffer register
633
      // Load first instruction to op_code register
634
      // Increment Program Counter
635
      {BOOT_3, 16'b????????????????} :
636
         begin
637
           next_cpu_state   = CONT;
638
           ena_rd_low_byte  = 1'b1;
639
           ena_rd_high_byte = 1'b1;
640
           alu_result       = load_data;
641
         end
642
 
643 12 rehayes
      {BREAK, 16'b????????????????} :
644
         begin
645 17 rehayes
           if (!xge)
646
             next_cpu_state = IDLE;
647 53 rehayes
           else if (ss_mem_ack || !debug_active)
648 17 rehayes
             next_cpu_state = BREAK_2;
649
           else if (chid_goto_idle)
650
             next_cpu_state = CHG_CHID;
651
           else
652
             next_cpu_state = BREAK;
653 12 rehayes
           load_next_inst = 1'b0;
654 40 rehayes
           pc_incr_mux    = 16'h0000;
655
           next_pc        = pc_sum;
656 12 rehayes
         end
657
 
658
      {BREAK_2, 16'b????????????????} :
659
         begin
660
           next_cpu_state = LD_INST;
661
           load_next_inst = 1'b0;
662
         end
663
 
664
      {LD_INST, 16'b????????????????} :
665
         begin
666
           next_cpu_state = DEBUG;
667 40 rehayes
           pc_incr_mux    = 16'h0000;
668
           next_pc        = pc_sum;
669 12 rehayes
         end
670
 
671 2 rehayes
      {DEBUG, 16'b????????????????} :
672
         begin
673 17 rehayes
           if (!xge)
674
             next_cpu_state = IDLE;
675 53 rehayes
           else if (ss_mem_ack || !debug_active)
676 17 rehayes
             next_cpu_state = CONT;
677
           else if (cmd_change_pc)
678
             next_cpu_state = LD_INST;
679
           else if (chid_goto_idle)
680
             next_cpu_state = CHG_CHID;
681
           else
682
             next_cpu_state = DEBUG;
683
 
684 15 rehayes
           load_next_inst = cmd_change_pc;
685 40 rehayes
           pc_incr_mux    = 16'h0000;
686
           next_pc        = pc_sum;
687 2 rehayes
         end
688
 
689 12 rehayes
      // Pause here for program counter change of flow or memory write access
690 5 rehayes
      //  Load next instruction and increment PC
691 12 rehayes
      // Default next_cpu_state is CONT
692 5 rehayes
      {S_STALL, 16'b????????????????} :
693
         begin
694
         end
695
 
696
      // Pause here for memory read word access
697
      //  Load next instruction and increment PC
698 40 rehayes
      {W_LOAD, 16'b????????????????} :
699 5 rehayes
         begin
700
           alu_result       = load_data;
701
           ena_rd_low_byte  = 1'b1;
702
           ena_rd_high_byte = 1'b1;
703
         end
704
 
705
      // Pause here for memory read byte access
706
      //  Load next instruction and increment PC
707 40 rehayes
      {B_LOAD, 16'b????????????????} :
708 5 rehayes
         begin
709
           alu_result       = {8'h00, load_data[15:8]};
710
           ena_rd_low_byte  = 1'b1;
711
           ena_rd_high_byte = 1'b1;
712
         end
713
 
714 2 rehayes
      // -----------------------------------------------------------------------
715
      // Instruction Group -- Return to Scheduler and Others
716
      // -----------------------------------------------------------------------
717
 
718
      // Instruction = BRK, Op Code =  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
719
      // Cycles - PAff
720
      {CONT, 16'b0000000000000000} :
721
         begin
722 12 rehayes
           next_cpu_state   = BREAK;
723 40 rehayes
           pc_incr_mux      = 16'hfffe;  // equals -2
724
           next_pc          = pc_sum;
725 2 rehayes
           load_next_inst   = 1'b0;
726 12 rehayes
           brk_set_dbg      = 1'b1;
727 2 rehayes
         end
728
 
729
      // Instruction = NOP, Op Code =  0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
730
      {CONT, 16'b0000000100000000} :
731
         begin
732
         end
733
 
734
      // Instruction = RTS, Op Code =  0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
735
      // Cycles - PA
736
      {CONT, 16'b0000001000000000} :
737
         begin
738
           next_cpu_state   = IDLE;
739 40 rehayes
           pc_incr_mux      = 16'h0000;
740
           next_pc          = pc_sum;
741 2 rehayes
           load_next_inst   = 1'b0;
742
         end
743
 
744
      // Instruction = SIF, Op Code =  0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0
745
      // Sets the Interrupt Flag of the current channel (XGCHID) will be set.
746
      // Cycles - PA
747
      {CONT, 16'b0000001100000000} :
748
         begin
749
           set_irq_flag = xgchid;
750
         end
751
 
752
      // -----------------------------------------------------------------------
753
      // Instruction Group -- Semaphore Instructions
754
      // -----------------------------------------------------------------------
755
 
756
      // Instruction = CSEM IMM3, Op Code =  0 0 0 0 0 IMM3 1 1 1 1 0 0 0 0
757
      // Unlocks a semaphore that was locked by the RISC core.
758
      // Cycles - PA
759
      {CONT, 16'b00000???11110000} :
760
         begin
761
           clear_semaph = 1'b1;
762
           semaph_risc  = op_code[10:8];
763
         end
764
 
765
      // Instruction = CSEM RS, Op Code =  0 0 0 0 0 RS 1 1 1 1 0 0 0 1
766
      // Unlocks a semaphore that was locked by the RISC core.
767
      // In monadic address mode, bits RS[2:0] select the semaphore to be cleared.
768
      // Cycles - PA
769
      {CONT, 16'b00000???11110001} :
770
         begin
771
           clear_semaph = 1'b1;
772
           semaph_risc  = rd_data[2:0];
773
         end
774
 
775
      // Instruction = SSEM IMM3, Op Code =  0 0 0 0 0 IMM3 1 1 1 1 0 0 1 0
776
      // Attempts to set a semaphore. The state of the semaphore will be stored in the Carry-Flag:
777
      // 1 = Semaphore is locked by the RISC core
778
      // 0 = Semaphore is locked by the S12X_CPU
779
      // Cycles - PA
780
      {CONT, 16'b00000???11110010} :
781
         begin
782
           set_semaph  = 1'b1;
783
           semaph_risc = op_code[10:8];
784
 
785
           next_carry    = semaph_stat;
786
         end
787
 
788
      // Instruction = SSEM RS, Op Code =  0 0 0 0 0 RS 1 1 1 1 0 0 1 1
789
      // Attempts to set a semaphore. The state of the semaphore will be stored in the Carry-Flag:
790
      // 1 = Semaphore is locked by the RISC core
791
      // 0 = Semaphore is locked by the S12X_CPU
792
      // In monadic address mode, bits RS[2:0] select the semaphore to be set.
793
      // Cycles - PA
794
      {CONT, 16'b00000???11110011} :
795
         begin
796
           set_semaph  = 1'b1;
797
           semaph_risc = rd_data[2:0];
798
 
799
           next_carry    = semaph_stat;
800
         end
801
 
802
      // -----------------------------------------------------------------------
803
      // Instruction Group -- Single Register Instructions
804
      // -----------------------------------------------------------------------
805
 
806
      // Instruction = SEX RD, Op Code =  0 0 0 0 0 RD 1 1 1 1 0 1 0 0
807
      // SEX - Sign Extend Byte to Word
808
      // Cycles - P
809
      {CONT, 16'b00000???11110100} :
810
         begin
811
           ena_rd_high_byte = 1'b1;
812
 
813
           alu_result    = {{8{rd_data[7]}}, rd_data[7:0]};
814
           next_zero     = !(|alu_result);
815
           next_negative = alu_result[15];
816
           next_overflow = 1'b0;
817
         end
818
 
819
      // Instruction = PAR RD, Op Code =  0 0 0 0 0 RD 1 1 1 1 0 1 0 1
820
      // PAR - Calculate Parity
821
      // Set Carry Flag on odd number of bits
822
      // Cycles - P
823
      {CONT, 16'b00000???11110101} :
824
         begin
825
           next_zero     = !(|rd_data);
826
           next_negative = 1'b0;
827
           next_carry    = ^rd_data;
828
           next_overflow = 1'b0;
829
         end
830
 
831
      // Instruction = JAL RD, Op Code =  0 0 0 0 0 RD 1 1 1 1 0 1 1 0
832
      // Jump And Link
833
      // PC + $0002 => RD; RD => PC
834
      // Jumps to the address stored in RD and saves the return address in RD.
835
      // Cycles - PP
836
      {CONT, 16'b00000???11110110} :
837
         begin
838 5 rehayes
           next_cpu_state   = S_STALL;
839 2 rehayes
           load_next_inst   = 1'b0;
840
           ena_rd_low_byte  = 1'b1;
841
           ena_rd_high_byte = 1'b1;
842
           alu_result       = program_counter;
843
           next_pc          = rd_data;
844
         end
845
 
846
      // Instruction = SIF RS, Op Code =  0 0 0 0 0 RS 1 1 1 1 0 1 1 1
847
      // Sets the Interrupt Flag associated with the channel id number
848
      // contained in RS[6:0] is set. The content of RS[15:7] is ignored
849
      // Cycles - P
850
      {CONT, 16'b00000???11110111} :
851
         begin
852
           set_irq_flag = rd_data[6:0];
853
         end
854
 
855
      // -----------------------------------------------------------------------
856
      // Instruction Group -- Special Move instructions
857
      // -----------------------------------------------------------------------
858
 
859
      // Instruction = TFR RD,CCR, Op Code =  0 0 0 0 0 RD 1 1 1 1 1 0 0 0
860
      // Transfer from and to Special Registers
861
      // TFR RD,CCR: CCR => RD[3:0], 0 => RD[15:4]
862
      // Cycles - P
863
      {CONT, 16'b00000???11111000} :
864
         begin
865
           ena_rd_low_byte  = 1'b1;
866
           ena_rd_high_byte = 1'b1;
867
           alu_result       = {12'b0, negative_flag, zero_flag, overflow_flag, carry_flag};
868
         end
869
 
870
      // Instruction = TFR CCR,RS, Op Code =  0 0 0 0 0 RS 1 1 1 1 1 0 0 1
871
      // Transfer from and to Special Registers
872
      // TFR CCR,RD: RD[3:0] => CCR
873
      // Cycles - P
874
      {CONT, 16'b00000???11111001} :
875
         begin
876
           next_negative = rd_data[3];
877
           next_zero     = rd_data[2];
878
           next_overflow = rd_data[1];
879
           next_carry    = rd_data[0];
880
         end
881
 
882
      // Instruction = TFR RD,PC, Op Code =  0 0 0 0 0 RD 1 1 1 1 1 0 1 0
883
      // Transfer from and to Special Registers
884
      // TFR RD,PC: PC+4 => RD
885
      // Cycles - P
886
      {CONT, 16'b00000???11111010} :
887
         begin
888
           ena_rd_low_byte  = 1'b1;
889
           ena_rd_high_byte = 1'b1;
890
           alu_result       = next_pc;
891
         end
892
 
893
      // -----------------------------------------------------------------------
894
      // Instruction Group -- Shift instructions Dyadic
895
      // -----------------------------------------------------------------------
896
 
897
      // Instruction = BFFO RD, RS, Op Code =  0 0 0 0 1 RD RS 1 0 0 0 0
898
      // BFFO - Bit Field Find First One
899
      // FirstOne (RS) => RD
900
      // Cycles - P
901
      {CONT, 16'b00001??????10000} :
902
         begin
903
           ena_rd_low_byte  = 1'b1;
904
           ena_rd_high_byte = 1'b1;
905
 
906 26 rehayes
           casez (rs1_data)  // synopsys parallel_case
907 2 rehayes
             16'b1???_????_????_???? : alu_result = 16'h000f;
908
             16'b01??_????_????_???? : alu_result = 16'h000e;
909
             16'b001?_????_????_???? : alu_result = 16'h000d;
910
             16'b0001_????_????_???? : alu_result = 16'h000c;
911
             16'b0000_1???_????_???? : alu_result = 16'h000b;
912
             16'b0000_01??_????_???? : alu_result = 16'h000a;
913
             16'b0000_001?_????_???? : alu_result = 16'h0009;
914
             16'b0000_0001_????_???? : alu_result = 16'h0008;
915
             16'b0000_0000_1???_???? : alu_result = 16'h0007;
916
             16'b0000_0000_01??_???? : alu_result = 16'h0006;
917
             16'b0000_0000_001?_???? : alu_result = 16'h0005;
918
             16'b0000_0000_0001_???? : alu_result = 16'h0004;
919
             16'b0000_0000_0000_1??? : alu_result = 16'h0003;
920
             16'b0000_0000_0000_01?? : alu_result = 16'h0002;
921
             16'b0000_0000_0000_001? : alu_result = 16'h0001;
922
             16'b0000_0000_0000_0001 : alu_result = 16'h0000;
923
           endcase
924
           next_zero     = !(|alu_result);
925
           next_negative = 1'b0;
926
           next_carry    = !(|rs1_data);
927
           next_overflow = 1'b0;
928
         end
929
 
930
      // Instruction = ASR RD, RS, Op Code =  0 0 0 0 1 RD RS 1 0 0 0 1
931
      // ASR - Arithmetic Shift Right
932
      // n = RS
933
      // Cycles - P
934
      {CONT, 16'b00001??????10001} :
935
         begin
936
           shift_ammount  = {|rs1_data[15:4], rs1_data[3:0]};
937
           shift_filler   = {16{rd_data[15]}};
938 12 rehayes
 
939 2 rehayes
           ena_rd_low_byte  = 1'b1;
940
           ena_rd_high_byte = 1'b1;
941
           alu_result       = shift_out;
942
           next_zero        = !(|alu_result);
943
           next_negative    = alu_result[15];
944
           next_carry       = |rs1_data ? shift_rollover : carry_flag;
945
           next_overflow    = rd_data[15] ^ alu_result[15];  // Table and text disagree
946
         end
947
 
948
      // Instruction = CSL RD, RS, Op Code =  0 0 0 0 1 RD RS 1 0 0 1 0
949
      // CSL - Logical Shift Left with Carry
950
      // n = RS
951
      // Cycles - P
952
      {CONT, 16'b00001??????10010} :
953
         begin
954
           shift_left     = 1'b1;
955
           shift_ammount  = {|rs1_data[15:4], rs1_data[3:0]};
956
           shift_filler   = {16{carry_flag}};
957
 
958
           ena_rd_low_byte  = 1'b1;
959
           ena_rd_high_byte = 1'b1;
960
           alu_result       = shift_out;
961
           next_zero        = !(|alu_result);
962
           next_negative    = alu_result[15];
963
           next_carry       = |rs1_data ? shift_rollover : carry_flag;
964
           next_overflow    = rd_data[15] ^ alu_result[15];
965
         end
966
 
967
      // Instruction = CSR RD, RS, Op Code =  0 0 0 0 1 RD RS 1 0 0 1 1
968
      // Logical Shift Right with Carry
969
      // n = RS
970
      // Cycles - P
971
      {CONT, 16'b00001??????10011} :
972
         begin
973
           shift_ammount  = {|rs1_data[15:4], rs1_data[3:0]};
974
           shift_filler   = {16{carry_flag}};
975
 
976
           ena_rd_low_byte  = 1'b1;
977
           ena_rd_high_byte = 1'b1;
978
           alu_result       = shift_out;
979
           next_zero        = !(|alu_result);
980
           next_negative    = alu_result[15];
981
           next_carry       = |rs1_data ? shift_rollover : carry_flag;
982
           next_overflow    = rd_data[15] ^ alu_result[15];
983
         end
984
 
985
      // Instruction = LSL RD, RS, Op Code =  0 0 0 0 1 RD RS 1 0 1 0 0
986
      // Logical Shift Left
987
      // n = RS
988
      // Cycles - P
989
      {CONT, 16'b00001??????10100} :
990
         begin
991
           shift_left     = 1'b1;
992
           shift_ammount  = {|rs1_data[15:4], rs1_data[3:0]};
993
           shift_filler   = 16'h0000;
994
 
995
           ena_rd_low_byte  = 1'b1;
996
           ena_rd_high_byte = 1'b1;
997
           alu_result       = shift_out;
998
           next_zero        = !(|alu_result);
999
           next_negative    = alu_result[15];
1000
           next_carry       = |rs1_data ? shift_rollover : carry_flag;
1001
           next_overflow    = rd_data[15] ^ alu_result[15];
1002
         end
1003
 
1004
      // Instruction = LSR RD, RS, Op Code =  0 0 0 0 1 RD RS 1 0 1 0 1
1005
      // Logical Shift Right
1006
      // n = RS
1007
      // Cycles - P
1008
      {CONT, 16'b00001??????10101} :
1009
         begin
1010
           shift_ammount  = {|rs1_data[15:4], rs1_data[3:0]};
1011
           shift_filler   = 16'h0000;
1012
 
1013
           ena_rd_low_byte  = 1'b1;
1014
           ena_rd_high_byte = 1'b1;
1015
           alu_result       = shift_out;
1016
           next_zero        = !(|alu_result);
1017
           next_negative    = alu_result[15];
1018
           next_carry       = |rs1_data ? shift_rollover : carry_flag;
1019
           next_overflow    = rd_data[15] ^ alu_result[15];
1020
         end
1021
 
1022
      // Instruction = ROL RD, RS, Op Code =  0 0 0 0 1 RD RS 1 0 1 1 0
1023
      // Rotate Left
1024
      // n = RS
1025
      // Cycles - P
1026
      {CONT, 16'b00001??????10110} :
1027
         begin
1028
           shift_left     = 1'b1;
1029
           shift_ammount  = {1'b0, rs1_data[3:0]};
1030
           shift_filler   = rd_data;
1031
 
1032
           ena_rd_low_byte  = 1'b1;
1033
           ena_rd_high_byte = 1'b1;
1034
           alu_result       = shift_out;
1035
           next_zero        = !(|alu_result);
1036
           next_negative    = alu_result[15];
1037
           next_overflow    = 1'b0;
1038
         end
1039
 
1040
      // Instruction = ROR RD, RS, Op Code =  0 0 0 0 1 RD RS 1 0 1 1 1
1041
      // Rotate Right
1042
      // n = RS
1043
      // Cycles - P
1044
      {CONT, 16'b00001??????10111} :
1045
         begin
1046
           shift_ammount  = {1'b0, rs1_data[3:0]};
1047
           shift_filler   = rd_data;
1048
 
1049
           ena_rd_low_byte  = 1'b1;
1050
           ena_rd_high_byte = 1'b1;
1051
           alu_result       = shift_out;
1052
           next_zero        = !(|alu_result);
1053
           next_negative    = alu_result[15];
1054
           next_overflow    = 1'b0;
1055
         end
1056
 
1057
      // -----------------------------------------------------------------------
1058
      // Instruction Group -- Shift instructions immediate
1059
      // -----------------------------------------------------------------------
1060
 
1061
      // Instruction = ASR RD, #IMM4, Op Code =  0 0 0 0 1 RD IMM4 1 0 0 1
1062
      // ASR - Arithmetic Shift Right
1063
      // n = IMM4
1064
      // Cycles - P
1065
      {CONT, 16'b00001???????1001} :
1066
         begin
1067
           shift_ammount  = {!(|op_code[7:4]), op_code[7:4]};
1068
           shift_filler   = {16{rd_data[15]}};
1069 12 rehayes
 
1070 2 rehayes
           ena_rd_low_byte  = 1'b1;
1071
           ena_rd_high_byte = 1'b1;
1072
           alu_result       = shift_out;
1073
           next_zero        = !(|alu_result);
1074
           next_negative    = alu_result[15];
1075
           next_carry       = shift_rollover;
1076
           next_overflow    = rd_data[15] ^ alu_result[15];  // Table and text disagree
1077
         end
1078
 
1079
      // Instruction = CSL RD, #IMM4, Op Code =  0 0 0 0 1 RD IMM4 1 0 1 0
1080
      // CSL - Logical Shift Left with Carry
1081
      // n = IMM4
1082
      // Cycles - P
1083
      {CONT, 16'b00001???????1010} :
1084
         begin
1085
           shift_left     = 1'b1;
1086
           shift_ammount  = {!(|op_code[7:4]), op_code[7:4]};
1087
           shift_filler   = {16{carry_flag}};
1088 12 rehayes
 
1089 2 rehayes
           ena_rd_low_byte  = 1'b1;
1090
           ena_rd_high_byte = 1'b1;
1091
           alu_result       = shift_out;
1092
           next_zero        = !(|alu_result);
1093
           next_negative    = alu_result[15];
1094
           next_carry       = shift_rollover;
1095
           next_overflow    = rd_data[15] ^ alu_result[15];
1096
         end
1097
 
1098
      // Instruction = CSR RD, #IMM4, Op Code =  0 0 0 0 1 RD IMM4 1 0 1 1
1099
      // CSR - Logical Shift Right with Carry
1100
      // n = IMM4
1101
      // Cycles - P
1102
      {CONT, 16'b00001???????1011} :
1103
         begin
1104
           shift_ammount  = {!(|op_code[7:4]), op_code[7:4]};
1105
           shift_filler   = {16{carry_flag}};
1106
 
1107
           ena_rd_low_byte  = 1'b1;
1108
           ena_rd_high_byte = 1'b1;
1109
           alu_result       = shift_out;
1110
           next_zero        = !(|alu_result);
1111
           next_negative    = alu_result[15];
1112
           next_carry       = shift_rollover;
1113
           next_overflow    = rd_data[15] ^ alu_result[15];
1114
         end
1115
 
1116
      // Instruction = LSL RD, #IMM4, Op Code =  0 0 0 0 1 RD IMM4 1 1 0 0
1117
      // LSL - Logical Shift Left
1118
      // n = IMM4
1119
      // Cycles - P
1120
      {CONT, 16'b00001???????1100} :
1121
         begin
1122
           shift_left     = 1'b1;
1123
           shift_ammount  = {!(|op_code[7:4]), op_code[7:4]};
1124
           shift_filler   = 16'h0000;
1125 12 rehayes
 
1126 2 rehayes
           ena_rd_low_byte  = 1'b1;
1127
           ena_rd_high_byte = 1'b1;
1128
           alu_result       = shift_out;
1129
           next_zero        = !(|alu_result);
1130
           next_negative    = alu_result[15];
1131
           next_carry       = shift_rollover;
1132
           next_overflow    = rd_data[15] ^ alu_result[15];
1133
         end
1134
 
1135
      // Instruction = LSR RD, #IMM4, Op Code =  0 0 0 0 1 RD IMM4 1 1 0 1
1136
      // LSR - Logical Shift Right
1137
      // n = IMM4
1138
      // Cycles - P
1139
      {CONT, 16'b00001???????1101} :
1140
         begin
1141
           shift_ammount  = {!(|op_code[7:4]), op_code[7:4]};
1142
           shift_filler   = 16'h0000;
1143 12 rehayes
 
1144 2 rehayes
           ena_rd_low_byte  = 1'b1;
1145
           ena_rd_high_byte = 1'b1;
1146
           alu_result       = shift_out;
1147
           next_zero        = !(|alu_result);
1148
           next_negative    = alu_result[15];
1149
           next_carry       = shift_rollover;
1150
           next_overflow    = rd_data[15] ^ alu_result[15];
1151
         end
1152
 
1153
      // Instruction = ROL RD, #IMM4, Op Code =  0 0 0 0 1 RD IMM4 1 1 1 0
1154
      // ROL - Rotate Left
1155
      // n = IMM4
1156
      // Cycles - P
1157
      {CONT, 16'b00001???????1110} :
1158
         begin
1159
           shift_left     = 1'b1;
1160
           shift_ammount  = {1'b0, op_code[7:4]};
1161
           shift_filler   = rd_data;
1162 12 rehayes
 
1163 2 rehayes
           ena_rd_low_byte  = 1'b1;
1164
           ena_rd_high_byte = 1'b1;
1165
           alu_result       = shift_out;
1166
           next_zero        = !(|alu_result);
1167
           next_negative    = alu_result[15];
1168
           next_overflow    = 1'b0;
1169
         end
1170
 
1171
      // Instruction = ROR RD, #IMM4, Op Code =  0 0 0 0 1 RD IMM4 1 1 1 1
1172
      // ROR - Rotate Right
1173
      // n = IMM4
1174
      // Cycles - P
1175
      {CONT, 16'b00001???????1111} :
1176
         begin
1177
           shift_ammount  = {1'b0, op_code[7:4]};
1178
           shift_filler   = rd_data;
1179 12 rehayes
 
1180 2 rehayes
           ena_rd_low_byte  = 1'b1;
1181
           ena_rd_high_byte = 1'b1;
1182
           alu_result       = shift_out;
1183
           next_zero        = !(|alu_result);
1184
           next_negative    = alu_result[15];
1185
           next_overflow    = 1'b0;
1186
         end
1187
 
1188
      // -----------------------------------------------------------------------
1189
      // Instruction Group -- Logical Triadic
1190
      // -----------------------------------------------------------------------
1191
 
1192
      // Instruction = AND RD, RS1, RS2, Op Code =  0 0 0 1 0 RD RS1 RS2 0 0
1193
      // AND - Logical AND
1194
      // RS1 & RS2 => RD
1195
      // Cycles - P
1196
      {CONT, 16'b00010?????????00} :
1197
         begin
1198
           ena_rd_low_byte  = 1'b1;
1199
           ena_rd_high_byte = 1'b1;
1200
 
1201
           alu_result    = rs1_data & rs2_data;
1202
           next_zero     = !(|alu_result);
1203
           next_negative = alu_result[15];
1204
           next_overflow = 1'b0;
1205
         end
1206
 
1207
      // Instruction = OR RD, RS1, RS2, Op Code =  0 0 0 1 0 RD RS1 RS2 1 0
1208
      // OR - Logical OR
1209
      // RS1 | RS2 => RD
1210
      // Cycles - P
1211
      {CONT, 16'b00010?????????10} :
1212
         begin
1213
           ena_rd_low_byte  = 1'b1;
1214
           ena_rd_high_byte = 1'b1;
1215
 
1216
           alu_result    = rs1_data | rs2_data;
1217
           next_zero     = !(|alu_result);
1218
           next_negative = alu_result[15];
1219
           next_overflow = 1'b0;
1220
          end
1221
 
1222
      // Instruction = XNOR RD, RS1, RS2, Op Code =  0 0 0 1 0 RD RS1 RS2 1 1
1223
      // XNOR - Logical Exclusive NOR
1224
      // ~(RS1 ^ RS2) => RD
1225
      // Cycles - P
1226
      {CONT, 16'b00010?????????11} :
1227
         begin
1228
           ena_rd_low_byte  = 1'b1;
1229
           ena_rd_high_byte = 1'b1;
1230
 
1231
           alu_result    = ~(rs1_data ^ rs2_data);
1232
           next_zero     = !(|alu_result);
1233
           next_negative = alu_result[15];
1234
           next_overflow = 1'b0;
1235
         end
1236
 
1237
      // -----------------------------------------------------------------------
1238
      // Instruction Group -- Arithmetic Triadic
1239
      // -----------------------------------------------------------------------
1240
 
1241
      // Instruction = SUB RD, RS1, RS2, Op Code =  0 0 0 1 1 RD RS1 RS2 0 0
1242
      // SUB - Subtract without Carry
1243
      // RS1 - RS2 => RD
1244
      // Cycles - P
1245
      {CONT, 16'b00011?????????00} :
1246
         begin
1247
           ena_rd_low_byte  = 1'b1;
1248
           ena_rd_high_byte = 1'b1;
1249
 
1250
           {next_carry, alu_result}    = rs1_data - rs2_data;
1251
           next_zero     = !(|alu_result);
1252
           next_negative = alu_result[15];
1253
           next_overflow = (rs1_data[15] && !rs2_data[15] && !alu_result[15]) || (!rs1_data[15] && rs2_data[15] && alu_result[15]);
1254
         end
1255
 
1256
      // Instruction = SBC RD, RS1, RS2, Op Code =  0 0 0 1 1 RD RS1 RS2 0 1
1257
      // SBC - Subtract with Carry
1258
      // RS1 - RS2 - C => RD
1259
      // Cycles - P
1260
      {CONT, 16'b00011?????????01} :
1261
         begin
1262
           ena_rd_low_byte  = 1'b1;
1263
           ena_rd_high_byte = 1'b1;
1264
 
1265
           {next_carry, alu_result}    = rs1_data - rs2_data - {15'b0, carry_flag};
1266 47 rehayes
           next_zero     = !(|alu_result) && zero_flag;
1267 2 rehayes
           next_negative = alu_result[15];
1268
           next_overflow = (rs1_data[15] && !rs2_data[15] && !alu_result[15]) || (!rs1_data[15] && rs2_data[15] && alu_result[15]);
1269
         end
1270
 
1271
      // Instruction = ADD RD, RS1, RS2, Op Code =  0 0 0 1 1 RD RS1 RS2 1 0
1272
      // ADD - ADD without carry
1273
      // RS1 + RS2 => RD
1274
      // Cycles - P
1275
      {CONT, 16'b00011?????????10} :
1276
         begin
1277
           ena_rd_low_byte  = 1'b1;
1278
           ena_rd_high_byte = 1'b1;
1279
 
1280
           {next_carry, alu_result}    = rs1_data + rs2_data;
1281
           next_zero     = !(|alu_result);
1282
           next_negative = alu_result[15];
1283
           next_overflow = (rs1_data[15] && rs2_data[15] && !alu_result[15]) || (!rs1_data[15] && !rs2_data[15] && alu_result[15]);
1284
         end
1285
 
1286
      // Instruction = ADC RD, RS1, RS2, Op Code =  0 0 0 1 1 RD RS1 RS2 1 1
1287
      // ADC - add with carry
1288
      // RS1 + RS2 + C => RD
1289
      // Cycles - P
1290
      {CONT, 16'b00011?????????11} :
1291
         begin
1292
           ena_rd_low_byte  = 1'b1;
1293
           ena_rd_high_byte = 1'b1;
1294
 
1295
           {next_carry, alu_result}    = rs1_data + rs2_data + {15'b0, carry_flag};
1296 47 rehayes
           next_zero     = !(|alu_result) && zero_flag;
1297 2 rehayes
           next_negative = alu_result[15];
1298
           next_overflow = (rs1_data[15] && rs2_data[15] && !alu_result[15]) || (!rs1_data[15] && !rs2_data[15] && alu_result[15]);
1299
         end
1300
 
1301
      // -----------------------------------------------------------------------
1302
      // Instruction Group -- Branches
1303
      // -----------------------------------------------------------------------
1304
 
1305
      // Instruction = BCC REL9, Op Code =  0 0 1 0 0 0 0 REL9
1306
      // Branch if Carry Cleared
1307
      // If C = 0, then PC + $0002 + (REL9 << 1) => PC
1308
      // Cycles - PP/P
1309
      {CONT, 16'b0010000?????????} :
1310
         begin
1311
           if (!carry_flag)
1312
             begin
1313 5 rehayes
               next_cpu_state = S_STALL;
1314 2 rehayes
               load_next_inst = 1'b0;
1315 40 rehayes
               pc_incr_mux    = jump_offset;
1316
               next_pc        = pc_sum;  // There is a race condition when the default declaration is used
1317 2 rehayes
             end
1318
         end
1319
 
1320
      // Instruction = BCS REL9, Op Code =  0 0 1 0 0 0 1 REL9
1321
      // Branch if Carry Set
1322
      // If C = 1, then PC + $0002 + (REL9 << 1) => PC
1323
      // Cycles - PP/P
1324
      {CONT, 16'b0010001?????????} :
1325
         begin
1326
           if (carry_flag)
1327
             begin
1328 5 rehayes
               next_cpu_state = S_STALL;
1329 2 rehayes
               load_next_inst = 1'b0;
1330 40 rehayes
               pc_incr_mux    = jump_offset;
1331
               next_pc        = pc_sum;
1332 2 rehayes
             end
1333
         end
1334
 
1335
      // Instruction = BNE REL9, Op Code =  0 0 1 0 0 1 0 REL9
1336
      // Branch if Not Equal
1337
      // If Z = 0, then PC + $0002 + (REL9 << 1) => PC
1338
      // Cycles - PP/P
1339
      {CONT, 16'b0010010?????????} :
1340
         begin
1341
           if (!zero_flag)
1342
             begin
1343 5 rehayes
               next_cpu_state = S_STALL;
1344 2 rehayes
               load_next_inst = 1'b0;
1345 40 rehayes
               pc_incr_mux    = jump_offset;
1346
               next_pc        = pc_sum;
1347 2 rehayes
             end
1348
         end
1349
 
1350
      // Instruction = BEQ REL9, Op Code =  0 0 1 0 0 1 1 REL9
1351
      // Branch if Equal
1352
      // If Z = 1, then PC + $0002 + (REL9 << 1) => PC
1353
      // Cycles - PP/P
1354
      {CONT, 16'b0010011?????????} :
1355
         begin
1356
           if (zero_flag)
1357
             begin
1358 5 rehayes
               next_cpu_state = S_STALL;
1359 2 rehayes
               load_next_inst = 1'b0;
1360 40 rehayes
               pc_incr_mux    = jump_offset;
1361
               next_pc        = pc_sum;
1362 2 rehayes
             end
1363
         end
1364
 
1365
      // Instruction = BPL REL9, Op Code =  0 0 1 0 1 0 0 REL9
1366
      // Branch if Plus
1367
      // If N = 0, then PC + $0002 + (REL9 << 1) => PC
1368
      // Cycles - PP/P
1369
      {CONT, 16'b0010100?????????} :
1370
         begin
1371
           if (!negative_flag)
1372
             begin
1373 5 rehayes
               next_cpu_state = S_STALL;
1374 2 rehayes
               load_next_inst = 1'b0;
1375 40 rehayes
               pc_incr_mux    = jump_offset;
1376
               next_pc        = pc_sum;
1377 2 rehayes
             end
1378
         end
1379
 
1380
      // Instruction = BMI REL9, Op Code =  0 0 1 0 1 0 1 REL9
1381
      // Branch if Minus
1382
      // If N = 1, then PC + $0002 + (REL9 << 1) => PC
1383
      // Cycles - PP/P
1384
      {CONT, 16'b0010101?????????} :
1385
         begin
1386
           if (negative_flag)
1387
             begin
1388 5 rehayes
               next_cpu_state = S_STALL;
1389 2 rehayes
               load_next_inst = 1'b0;
1390 40 rehayes
               pc_incr_mux    = jump_offset;
1391
               next_pc        = pc_sum;
1392 2 rehayes
             end
1393
         end
1394
 
1395
      // Instruction = BVC REL9, Op Code =  0 0 1 0 1 1 0 REL9
1396
      // Branch if Overflow Cleared
1397
      // If V = 0, then PC + $0002 + (REL9 << 1) => PC
1398
      // Cycles - PP/P
1399
      {CONT, 16'b0010110?????????} :
1400
         begin
1401
           if (!overflow_flag)
1402
             begin
1403 5 rehayes
               next_cpu_state = S_STALL;
1404 2 rehayes
               load_next_inst = 1'b0;
1405 40 rehayes
               pc_incr_mux    = jump_offset;
1406
               next_pc        = pc_sum;
1407 2 rehayes
             end
1408
         end
1409
 
1410
      // Instruction = BVS REL9, Op Code =  0 0 1 0 1 1 1 REL9
1411
      // Branch if Overflow Set
1412
      // If V = 1, then PC + $0002 + (REL9 << 1) => PC
1413
      // Cycles - PP/P
1414
      {CONT, 16'b0010111?????????} :
1415
         begin
1416
           if (overflow_flag)
1417
             begin
1418 5 rehayes
               next_cpu_state = S_STALL;
1419 2 rehayes
               load_next_inst = 1'b0;
1420 40 rehayes
               pc_incr_mux    = jump_offset;
1421
               next_pc        = pc_sum;
1422 2 rehayes
             end
1423
         end
1424
 
1425
      // Instruction = BHI REL9, Op Code =  0 0 1 1 0 0 0 REL9
1426
      // Branch if Higher
1427
      // If C | Z = 0, then PC + $0002 + (REL9 << 1) => PC
1428
      // Cycles - PP/P
1429
      {CONT, 16'b0011000?????????} :
1430
         begin
1431
           if (!(carry_flag || zero_flag))
1432
             begin
1433 5 rehayes
               next_cpu_state = S_STALL;
1434 2 rehayes
               load_next_inst = 1'b0;
1435 40 rehayes
               pc_incr_mux    = jump_offset;
1436
               next_pc        = pc_sum;
1437 2 rehayes
             end
1438
         end
1439
 
1440
      // Instruction = BLS REL9, Op Code =  0 0 1 1 0 0 1 REL9
1441
      // Branch if Lower or Same
1442
      // If C | Z = 1, then PC + $0002 + (REL9 << 1) => PC
1443
      // Cycles - PP/P
1444
      {CONT, 16'b0011001?????????} :
1445
         begin
1446
           if (carry_flag || zero_flag)
1447
             begin
1448 5 rehayes
               next_cpu_state = S_STALL;
1449 2 rehayes
               load_next_inst = 1'b0;
1450 40 rehayes
               pc_incr_mux    = jump_offset;
1451
               next_pc        = pc_sum;
1452 2 rehayes
             end
1453
         end
1454
 
1455
      // Instruction = BGE REL9, Op Code =  0 0 1 1 0 1 0 REL9
1456
      // Branch if Greater than or Equal to Zero
1457
      // If N ^ V = 0, then PC + $0002 + (REL9 << 1) => PC
1458
      // Cycles - PP/P
1459
      {CONT, 16'b0011010?????????} :
1460
         begin
1461
           if (!(negative_flag ^ overflow_flag))
1462
             begin
1463 5 rehayes
               next_cpu_state = S_STALL;
1464 2 rehayes
               load_next_inst = 1'b0;
1465 40 rehayes
               pc_incr_mux    = jump_offset;
1466
               next_pc        = pc_sum;
1467 2 rehayes
             end
1468
         end
1469
 
1470
      // Instruction = BLT REL9, Op Code =  0 0 1 1 0 1 1 REL9
1471
      // Branch if Lower than Zero
1472
      // If N ^ V = 1, then PC + $0002 + (REL9 << 1) => PC
1473
      // Cycles - PP/P
1474
      {CONT, 16'b0011011?????????} :
1475
         begin
1476
           if (negative_flag ^ overflow_flag)
1477
             begin
1478 5 rehayes
               next_cpu_state = S_STALL;
1479 2 rehayes
               load_next_inst = 1'b0;
1480 40 rehayes
               pc_incr_mux    = jump_offset;
1481
               next_pc        = pc_sum;
1482 2 rehayes
             end
1483
         end
1484
 
1485
      // Instruction = BGT REL9, Op Code =  0 0 1 1 1 0 0 REL9
1486
      // Branch if Greater than Zero
1487
      // If Z | (N ^ V) = 0, then PC + $0002 + (REL9 << 1) => PC
1488
      // Cycles - PP/P
1489
      {CONT, 16'b0011100?????????} :
1490
         begin
1491
           if (!(zero_flag || (negative_flag ^ overflow_flag)))
1492
             begin
1493 5 rehayes
               next_cpu_state = S_STALL;
1494 2 rehayes
               load_next_inst = 1'b0;
1495 40 rehayes
               pc_incr_mux    = jump_offset;
1496
               next_pc        = pc_sum;
1497 2 rehayes
             end
1498
         end
1499
 
1500
      // Instruction = BLE REL9, Op Code =  0 0 1 1 1 0 1 REL9
1501
      // Branch if Less or Equal to Zero
1502
      // If Z | (N ^ V) = 1, then PC + $0002 + (REL9 << 1) => PC
1503
      // Cycles - PP/P
1504
      {CONT, 16'b0011101?????????} :
1505
         begin
1506
           if (zero_flag || (negative_flag ^ overflow_flag))
1507
             begin
1508 5 rehayes
               next_cpu_state = S_STALL;
1509 2 rehayes
               load_next_inst = 1'b0;
1510 40 rehayes
               pc_incr_mux    = jump_offset;
1511
               next_pc        = pc_sum;
1512 2 rehayes
             end
1513
         end
1514
 
1515
      // Instruction = BRA REL10, Op Code =  0 0 1 1 1 1 REL10
1516
      // Branch Always, signed offset
1517
      // PC + $0002 + (REL10 << 1) => PC
1518
      // Cycles - PP
1519
      {CONT, 16'b001111??????????} :
1520
         begin
1521 5 rehayes
           next_cpu_state = S_STALL;
1522 2 rehayes
           load_next_inst = 1'b0;
1523 40 rehayes
           pc_incr_mux    = bra_offset;
1524
           next_pc        = pc_sum;
1525 2 rehayes
         end
1526
 
1527
 
1528
      // -----------------------------------------------------------------------
1529
      // Instruction Group -- Load and Store Instructions
1530
      // -----------------------------------------------------------------------
1531
 
1532
      // Instruction = LDB RD, (RB, #OFFS5), Op Code =  0 1 0 0 0 RD RB OFFS5
1533
      // Load Byte from Memory, unsigned offset
1534
      // M[RB, #OFFS5] => RD.L; $00 => RD.H
1535
      // RB field == RS1 field
1536
      // Cycles - Pr
1537
      {CONT, 16'b01000???????????} :
1538
         begin
1539 40 rehayes
           next_cpu_state = B_LOAD;
1540 2 rehayes
           load_next_inst = 1'b0;
1541 40 rehayes
           pc_incr_mux    = 16'h0000;
1542
           next_pc        = pc_sum;
1543 2 rehayes
           data_access    = 1'b1;
1544
           data_address   = rs1_data + {11'b0, op_code[4:0]};
1545
         end
1546
 
1547
      // Instruction = LDW RD, (RB, #OFFS5), Op Code =  0 1 0 0 1 RD RB OFFS5
1548
      // Load Word from Memory, unsigned offset
1549
      // M[RB, #OFFS5] => RD
1550
      // RB field == RS1 field
1551
      // Cycles - PR
1552
      {CONT, 16'b01001???????????} :
1553
         begin
1554 40 rehayes
           next_cpu_state = W_LOAD;
1555 2 rehayes
           load_next_inst = 1'b0;
1556 40 rehayes
           pc_incr_mux    = 16'h0000;
1557
           next_pc        = pc_sum;
1558 2 rehayes
           data_access    = 1'b1;
1559
           data_address   = rs1_data + {11'b0, op_code[4:0]};
1560
           data_word_op   = 1'b1;
1561
         end
1562
 
1563
      // Instruction = STB RS, (RB, #OFFS5), Op Code =  0 1 0 1 0 RS RB OFFS5
1564
      // Store Byte to Memory, unsigned offset
1565
      // RS.L => M[RB, #OFFS5]
1566
      // RS field == RD fieild, RB field == RS1 field
1567
      // Cycles - Pw
1568
      {CONT, 16'b01010???????????} :
1569
         begin
1570 5 rehayes
           next_cpu_state = S_STALL;
1571 2 rehayes
           load_next_inst = 1'b0;
1572 40 rehayes
           pc_incr_mux    = 16'h0000;
1573
           next_pc        = pc_sum;
1574 2 rehayes
           data_access    = 1'b1;
1575
           data_write     = 1'b1;
1576
           data_address   = rs1_data + {11'b0, op_code[4:0]};
1577
         end
1578
 
1579
      // Instruction = STW RS, (RB, #OFFS5), Op Code =  0 1 0 1 1 RS RB OFFS5
1580
      // Store Word to Memory, unsigned offset
1581
      // RS => M[RB, #OFFS5]
1582
      // RS field == RD fieild, RB field == RS1 field
1583
      // Cycles - PW
1584
      {CONT, 16'b01011???????????} :
1585
         begin
1586 5 rehayes
           next_cpu_state = S_STALL;
1587 2 rehayes
           load_next_inst = 1'b0;
1588 40 rehayes
           pc_incr_mux    = 16'h0000;
1589
           next_pc        = pc_sum;
1590 2 rehayes
           data_access    = 1'b1;
1591
           data_write     = 1'b1;
1592
           data_address   = rs1_data + {11'b0, op_code[4:0]};
1593
           data_word_op   = 1'b1;
1594
         end
1595
 
1596
      // Instruction = LDB RD, (RB, RI), Op Code =  0 1 1 0 0 RD RB RI 0 0
1597
      // Load Byte from Memory
1598
      // M[RB, RI] => RD.L; $00 => RD.H
1599
      // RB field == RS1 field, RI field == RS2 field
1600
      // Cycles - Pr
1601
      {CONT, 16'b01100?????????00} :
1602
         begin
1603 40 rehayes
           next_cpu_state = B_LOAD;
1604 2 rehayes
           load_next_inst = 1'b0;
1605 40 rehayes
           pc_incr_mux    = 16'h0000;
1606
           next_pc        = pc_sum;
1607 2 rehayes
           data_access    = 1'b1;
1608
           data_address   = rs1_data + rs2_data;
1609
         end
1610
 
1611
      // Instruction = LDW RD, (RB, RI), Op Code =  0 1 1 0 1 RD RB RI 0 0
1612
      // Load Word from Memory
1613
      // M[RB, RI] => RD
1614
      // RB field == RS1 field, RI field == RS2 field
1615
      // Cycles - PR
1616
      {CONT, 16'b01101?????????00} :
1617
         begin
1618 40 rehayes
           next_cpu_state = W_LOAD;
1619 2 rehayes
           load_next_inst = 1'b0;
1620 40 rehayes
           pc_incr_mux    = 16'h0000;
1621
           next_pc        = pc_sum;
1622 2 rehayes
           data_access    = 1'b1;
1623
           data_address   = rs1_data + rs2_data;
1624
           data_word_op   = 1'b1;
1625
         end
1626
 
1627
      // Instruction = STB RS, (RB, RI), Op Code =  0 1 1 1 0 RS RB RI 0 0
1628
      // RS.L => M[RB, RI]
1629
      // Store Byte to Memory
1630
      // RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
1631
      // Cycles - Pw
1632
      {CONT, 16'b01110?????????00} :
1633
         begin
1634 5 rehayes
           next_cpu_state = S_STALL;
1635 2 rehayes
           load_next_inst = 1'b0;
1636 40 rehayes
           pc_incr_mux    = 16'h0000;
1637
           next_pc        = pc_sum;
1638 2 rehayes
           data_access    = 1'b1;
1639
           data_write     = 1'b1;
1640
           data_address   = rs1_data + rs2_data;
1641
         end
1642
 
1643
      // Instruction = STW RS, (RB, RI), Op Code =  0 1 1 1 1 RS RB RI 0 0
1644
      // Store Word to Memory
1645
      // RS => M[RB, RI]
1646
      // RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
1647
      // Cycles - PW
1648
      {CONT, 16'b01111?????????00} :
1649
         begin
1650 5 rehayes
           next_cpu_state = S_STALL;
1651 2 rehayes
           load_next_inst = 1'b0;
1652 40 rehayes
           pc_incr_mux    = 16'h0000;
1653
           next_pc        = pc_sum;
1654 2 rehayes
           data_access    = 1'b1;
1655
           data_write     = 1'b1;
1656
           data_address   = rs1_data + rs2_data;
1657
           data_word_op   = 1'b1;
1658
         end
1659
 
1660
      // Instruction = LDB RD, (RB, RI+), Op Code =  0 1 1 0 0 RD RB RI 0 1
1661
      // Load Byte from Memory
1662
      // M[RB, RI] => RD.L; $00 => RD.H; RI+1 => RI
1663
      //  If the same general purpose register is used as index (RI) and destination register (RD),
1664
      //  the content of the register will not be incremented after the data move: M[RB, RI] => RD.L; $00 => RD.H
1665
      // RB field == RS1 field, RI field == RS2 field
1666
      // Cycles - Pr
1667
      {CONT, 16'b01100?????????01} :
1668
         begin
1669 40 rehayes
           next_cpu_state   = B_LOAD;
1670 2 rehayes
           load_next_inst   = 1'b0;
1671 40 rehayes
           pc_incr_mux      = 16'h0000;
1672
           next_pc          = pc_sum;
1673 2 rehayes
           data_access      = 1'b1;
1674
           data_address     = rs1_data + rs2_data;
1675
           alu_result       = rs2_data + 16'h0001;
1676 12 rehayes
           sel_rd_field     = 1'b0;
1677 2 rehayes
           ena_rd_low_byte  = 1'b1;
1678
           ena_rd_high_byte = 1'b1;
1679
         end
1680
 
1681
      // Instruction = LDW RD, (RB, RI+), Op Code =  0 1 1 0 1 RD RB RI 0 1
1682
      // Load Word from Memory
1683
      // M[RB, RI] => RD; RI+2 => RI
1684
      //  If the same general purpose register is used as index (RI) and destination register (RD),
1685
      //  the content of the register will not be incremented after the data move: M[RB, RI] => RD
1686
      // RB field == RS1 field, RI field == RS2 field
1687
      // Cycles - PR
1688
      {CONT, 16'b01101?????????01} :
1689
         begin
1690 40 rehayes
           next_cpu_state   = W_LOAD;
1691 2 rehayes
           load_next_inst   = 1'b0;
1692 40 rehayes
           pc_incr_mux      = 16'h0000;
1693
           next_pc          = pc_sum;
1694 2 rehayes
           data_access      = 1'b1;
1695
           data_address     = rs1_data + rs2_data;
1696
           data_word_op     = 1'b1;
1697
           alu_result       = rs2_data + 16'h0002;
1698 12 rehayes
           sel_rd_field     = 1'b0;
1699 2 rehayes
           ena_rd_low_byte  = 1'b1;
1700
           ena_rd_high_byte = 1'b1;
1701
         end
1702
 
1703
      // Instruction = STB RS, (RB, RI+), Op Code =  0 1 1 1 0 RS RB RI 0 1
1704
      // Store Byte to Memory
1705
      // RS.L => M[RB, RI]; RI+1 => RI
1706
      // RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
1707
      // Cycles - Pw
1708
      {CONT, 16'b01110?????????01} :
1709
         begin
1710 5 rehayes
           next_cpu_state   = S_STALL;
1711 2 rehayes
           load_next_inst   = 1'b0;
1712 40 rehayes
           pc_incr_mux      = 16'h0000;
1713
           next_pc          = pc_sum;
1714 2 rehayes
           data_access      = 1'b1;
1715
           data_write       = 1'b1;
1716
           data_address     = rs1_data + rs2_data;
1717
           alu_result       = rs2_data + 16'h0001;
1718 12 rehayes
           sel_rd_field     = 1'b0;
1719 2 rehayes
           ena_rd_low_byte  = 1'b1;
1720
           ena_rd_high_byte = 1'b1;
1721
         end
1722
 
1723
      // Instruction = STW RS, (RB, RI+), Op Code =  0 1 1 1 1 RS RB RI 0 1
1724
      // Store Word to Memory
1725
      // RS => M[RB, RI]; RI+2 => RI
1726
      // RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
1727
      // Cycles - PW
1728
      {CONT, 16'b01111?????????01} :
1729
         begin
1730 5 rehayes
           next_cpu_state   = S_STALL;
1731 2 rehayes
           load_next_inst   = 1'b0;
1732 40 rehayes
           pc_incr_mux      = 16'h0000;
1733
           next_pc          = pc_sum;
1734 2 rehayes
           data_access      = 1'b1;
1735
           data_write       = 1'b1;
1736
           data_word_op     = 1'b1;
1737
           data_address     = rs1_data + rs2_data;
1738
           alu_result       = rs2_data + 16'h0002;
1739 12 rehayes
           sel_rd_field     = 1'b0;
1740 2 rehayes
           ena_rd_low_byte  = 1'b1;
1741
           ena_rd_high_byte = 1'b1;
1742
         end
1743
 
1744
      // Instruction = LDB RD, (RB, -RI), Op Code =  0 1 1 0 0 RD RB RI 1 0
1745
      // Load Byte from Memory
1746
      // RI-1 => RI; M[RS, RI]  => RD.L; $00 => RD.H
1747
      // RB field == RS1 field, RI field == RS2 field
1748
      // Cycles - Pr
1749
      {CONT, 16'b01100?????????10} :
1750
         begin
1751 40 rehayes
           next_cpu_state   = B_LOAD;
1752 2 rehayes
           load_next_inst   = 1'b0;
1753 40 rehayes
           pc_incr_mux      = 16'h0000;
1754
           next_pc          = pc_sum;
1755 2 rehayes
           data_access      = 1'b1;
1756
           alu_result       = rs2_data + 16'hffff;
1757
           data_address     = rs1_data + alu_result;
1758 12 rehayes
           sel_rd_field     = 1'b0;
1759 2 rehayes
           ena_rd_low_byte  = 1'b1;
1760
           ena_rd_high_byte = 1'b1;
1761
         end
1762
 
1763
      // Instruction = LDW RD, (RB, -RI), Op Code =  0 1 1 0 1 RD RB RI 1 0
1764
      // Load Word from Memory
1765
      // RI-2 => RI; M[RS, RI] => RD
1766
      // RB field == RS1 field, RI field == RS2 field
1767
      // Cycles - PR
1768
      {CONT, 16'b01101?????????10} :
1769
         begin
1770 40 rehayes
           next_cpu_state   = W_LOAD;
1771 2 rehayes
           load_next_inst   = 1'b0;
1772 40 rehayes
           pc_incr_mux      = 16'h0000;
1773
           next_pc          = pc_sum;
1774 2 rehayes
           data_access      = 1'b1;
1775
           alu_result       = rs2_data + 16'hfffe;
1776
           data_address     = rs1_data + alu_result;
1777
           data_word_op     = 1'b1;
1778 12 rehayes
           sel_rd_field     = 1'b0;
1779 2 rehayes
           ena_rd_low_byte  = 1'b1;
1780
           ena_rd_high_byte = 1'b1;
1781
         end
1782
 
1783
      // Instruction = STB RS, (RB, -RI), Op Code =  0 1 1 1 0 RS RB RI 1 0
1784
      // Store Byte to Memory
1785
      // RI-1 => RI; RS.L => M[RB, RI]
1786
      //  If the same general purpose register is used as index (RI) and source register (RS),
1787
      //  the unmodified content of the source register is written to the memory: RS.L => M[RB, RS-1]; RS-1 => RS
1788
      // RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
1789
      // Cycles - Pw
1790
      {CONT, 16'b01110?????????10} :
1791
         begin
1792 5 rehayes
           next_cpu_state   = S_STALL;
1793 2 rehayes
           load_next_inst   = 1'b0;
1794 40 rehayes
           pc_incr_mux      = 16'h0000;
1795
           next_pc          = pc_sum;
1796 2 rehayes
           data_access      = 1'b1;
1797
           data_write       = 1'b1;
1798
           alu_result       = rs2_data + 16'hffff;
1799
           data_address     = rs1_data + alu_result;
1800 12 rehayes
           sel_rd_field     = 1'b0;
1801 2 rehayes
           ena_rd_low_byte  = 1'b1;
1802
           ena_rd_high_byte = 1'b1;
1803
         end
1804
 
1805
      // Instruction = STW RS, (RB, -RI), Op Code =  0 1 1 1 1 RS RB RI 1 0
1806
      // Store Word to Memory
1807
      // RI-2 => RI; RS => M[RB, RI]
1808
      //  If the same general purpose register is used as index (RI) and source register (RS),
1809
      //  the unmodified content of the source register is written to the memory: RS => M[RB, RS-2]; RS-2 => RS
1810
      // RS field == RD fieild, RB field == RS1 field, RI field == RS2 field
1811
      // Cycles - PW
1812
      {CONT, 16'b01111?????????10} :
1813
         begin
1814 5 rehayes
           next_cpu_state   = S_STALL;
1815 2 rehayes
           load_next_inst   = 1'b0;
1816 40 rehayes
           pc_incr_mux      = 16'h0000;
1817
           next_pc          = pc_sum;
1818 2 rehayes
           data_access      = 1'b1;
1819
           data_write       = 1'b1;
1820
           data_word_op     = 1'b1;
1821
           alu_result       = rs2_data + 16'hfffe;
1822
           data_address     = rs1_data + alu_result;
1823 12 rehayes
           sel_rd_field     = 1'b0;
1824 2 rehayes
           ena_rd_low_byte  = 1'b1;
1825
           ena_rd_high_byte = 1'b1;
1826
         end
1827
 
1828
      // -----------------------------------------------------------------------
1829
      // Instruction Group -- Bit Field Instructions
1830
      // -----------------------------------------------------------------------
1831
 
1832
      // Instruction = BFEXT RD, RS1, RS2, Op Code =  0 1 1 0 0 RD RS1 RS2 1 1
1833
      // BFEXT - Bit Field Extract
1834
      // RS1[(o+w):o] => RD[w:0]; 0 => RD[15:(w+1)]
1835
      // Cycles - P
1836
      {CONT, 16'b01100?????????11} :
1837
         begin
1838 5 rehayes
           ena_rd_low_byte  = 1'b1;
1839 2 rehayes
           ena_rd_high_byte = 1'b1;
1840
           shift_ammount  = {1'b0, rs2_data[3:0]};
1841
           for (bfi = 0; bfi <= 15; bfi = bfi + 1)
1842
             shift_in[bfi] = bf_mux_mask[bfi] ? rs1_data[bfi] : 1'b0;
1843
 
1844
           alu_result    = shift_out;
1845
           next_zero     = !(|alu_result);
1846
           next_negative = alu_result[15];
1847
           next_overflow = 1'b0;
1848
         end
1849
 
1850
      // Instruction = BFINS RD, RS1, RS2, Op Code =  0 1 1 0 1 RD RS1 RS2 1 1
1851
      // BFINS - Bit Field Insert
1852
      // RS1[w:0] => RD[(w+o):o
1853
      // Cycles - P
1854
      {CONT, 16'b01101?????????11} :
1855
         begin
1856
           ena_rd_low_byte  = 1'b1;
1857
           ena_rd_high_byte = 1'b1;
1858
           shift_left     = 1'b1;
1859
           shift_ammount  = {1'b0, rs2_data[3:0]};
1860
           shift_in       = rs1_data;
1861
 
1862
           for (bfi = 0; bfi <= 15; bfi = bfi + 1)
1863
             alu_result[bfi] = bf_mux_mask[bfi] ? shift_out[bfi] : rd_data[bfi];
1864
           next_zero     = !(|alu_result);
1865
           next_negative = alu_result[15];
1866
           next_overflow = 1'b0;
1867
         end
1868
 
1869
      // Instruction = BFINSI RD, RS1, RS2, Op Code =  0 1 1 1 0 RD RS1 RS2 1 1
1870
      // BFINSI - Bit Field Insert and Invert
1871
      // !RS1[w:0] => RD[w+o:o]
1872
      // Cycles - P
1873
      {CONT, 16'b01110?????????11} :
1874
         begin
1875
           ena_rd_low_byte  = 1'b1;
1876
           ena_rd_high_byte = 1'b1;
1877
           shift_left     = 1'b1;
1878
           shift_ammount  = {1'b0, rs2_data[3:0]};
1879
           shift_in       = rs1_data;
1880
 
1881
           for (bfi = 0; bfi <= 15; bfi = bfi + 1)
1882
             alu_result[bfi] = bf_mux_mask[bfi] ? !shift_out[bfi] : rd_data[bfi];
1883
           next_zero     = !(|alu_result);
1884
           next_negative = alu_result[15];
1885
           next_overflow = 1'b0;
1886
         end
1887
 
1888
      // Instruction = BFINSX RD, RS1, RS2, Op Code =  0 1 1 1 1 RD RS1 RS2 1 1
1889
      // BFINSX - Bit Field Insert and XNOR
1890
      // !(RS1[w:0] ^ RD[w+o:o]) => RD[w+o:o]
1891
      // Cycles - P
1892
      {CONT, 16'b01111?????????11} :
1893
         begin
1894
           ena_rd_low_byte  = 1'b1;
1895
           ena_rd_high_byte = 1'b1;
1896
           shift_left     = 1'b1;
1897
           shift_ammount  = {1'b0, rs2_data[3:0]};
1898
           shift_in       = rs1_data;
1899
 
1900 26 rehayes
           for (bfii = 0; bfii <= 15; bfii = bfii + 1)
1901
             alu_result[bfii] = bf_mux_mask[bfii] ? !(shift_out[bfii] ^ rd_data[bfii]) : rd_data[bfii];
1902 2 rehayes
           next_zero     = !(|alu_result);
1903
           next_negative = alu_result[15];
1904
           next_overflow = 1'b0;
1905
        end
1906
 
1907
      // -----------------------------------------------------------------------
1908
      // Instruction Group -- Logic Immediate Instructions
1909
      // -----------------------------------------------------------------------
1910
 
1911
      // Instruction = ANDL RD, #IMM8, Op Code =  1 0 0 0 0 RD IMM8
1912
      // AND - Logical AND
1913
      // RD.L & IMM8 => RD.L
1914
      // Cycles - P
1915
      {CONT, 16'b10000???????????} :
1916
         begin
1917
           ena_rd_low_byte = 1'b1;
1918
 
1919
           alu_result    = rd_data & {8'b0, op_code[7:0]};
1920
           next_zero     = !(|alu_result[7:0]);
1921
           next_negative = alu_result[7];
1922
           next_overflow = 1'b0;
1923
         end
1924
 
1925
      // Instruction = ANDH RD, #IMM8, Op Code =  1 0 0 0 1 RD IMM8
1926
      // AND - Logical AND
1927
      // RD.H & IMM8 => RD.H
1928
      // Cycles - P
1929
      {CONT, 16'b10001???????????} :
1930
         begin
1931
           ena_rd_high_byte = 1'b1;
1932
 
1933
           alu_result    = rd_data & {op_code[7:0], 8'b0};
1934
           next_zero     = !(|alu_result[15:8]);
1935
           next_negative = alu_result[15];
1936
           next_overflow = 1'b0;
1937
         end
1938
 
1939
      // Instruction = BITL RD, #IMM8, Op Code =  1 0 0 1 0 RD IMM8
1940
      // RD.L & IMM8 => NONE
1941
      {CONT, 16'b10010???????????} :
1942
         begin
1943
 
1944
           next_zero     = !(|(rd_data[7:0] & op_code[7:0]));
1945
           next_negative = rd_data[7] && op_code[7];
1946
           next_overflow = 1'b0;
1947
         end
1948
 
1949
      // Instruction = BITH RD, #IMM8, Op Code =  1 0 0 1 1 RD IMM8
1950
      // RD.H & IMM8 => NONE
1951
      {CONT, 16'b10011???????????} :
1952
         begin
1953
 
1954
           next_zero     = !(|(rd_data[15:8] & op_code[7:0]));
1955
           next_negative = rd_data[15] && op_code[7];
1956
           next_overflow = 1'b0;
1957
         end
1958
 
1959
      // Instruction = ORL RD, #IMM8, Op Code =  1 0 1 0 0 RD IMM8
1960
      // OR - Logical OR
1961
      // RD.L | IMM8 => RD.L
1962
      {CONT, 16'b10100???????????} :
1963
         begin
1964
           ena_rd_low_byte = 1'b1;
1965
 
1966
           alu_result    = rd_data | {8'b0, op_code[7:0]};
1967
           next_zero     = !(|alu_result[7:0]);
1968
           next_negative = alu_result[7];
1969
           next_overflow = 1'b0;
1970
         end
1971
 
1972
      // Instruction = ORH RD, #IMM8, Op Code =  1 0 1 0 1 RD IMM8
1973
      // OR - Logical OR
1974
      // RD.H | IMM8 => RD.H
1975
      {CONT, 16'b10101???????????} :
1976
         begin
1977
           ena_rd_high_byte = 1'b1;
1978
 
1979
           alu_result    = rd_data | {op_code[7:0], 8'b0};
1980
           next_zero     = !(|alu_result[15:8]);
1981
           next_negative = alu_result[15];
1982
           next_overflow = 1'b0;
1983
         end
1984
 
1985
      // Instruction = XNORL RD, #IMM8, Op Code =  1 0 1 1 0 RD IMM8
1986
      // XNOR - Logical Exclusive NOR
1987
      // ~(RD.L ^ IMM8) => RD.L
1988
      {CONT, 16'b10110???????????} :
1989
         begin
1990
           ena_rd_low_byte = 1'b1;
1991
 
1992
           alu_result    = ~(rd_data ^ {8'b0, op_code[7:0]});
1993
           next_zero     = !(|alu_result[7:0]);
1994
           next_negative = alu_result[7];
1995
           next_overflow = 1'b0;
1996
         end
1997
 
1998
      // Instruction = XNORH RD, #IMM8, Op Code =  1 0 1 1 1 RD IMM8
1999
      // XNOR - Logical Exclusive NOR
2000
      // ~(RD.H ^ IMM8) => RD.H
2001
      {CONT, 16'b10111???????????} :
2002
         begin
2003
           ena_rd_high_byte = 1'b1;
2004
 
2005
           alu_result    = ~(rd_data ^ {op_code[7:0], 8'b0});
2006
           next_zero     = !(|alu_result[15:8]);
2007
           next_negative = alu_result[15];
2008
           next_overflow = 1'b0;
2009
         end
2010
 
2011
      // -----------------------------------------------------------------------
2012
      // Instruction Group -- Arithmetic Immediate Instructions
2013
      // -----------------------------------------------------------------------
2014
 
2015
      // Instruction = SUBL RD, #IMM8, Op Code =  1 1 0 0 0 RD IMM8
2016
      // SUB - Subtract without Carry
2017
      // RD - $00:IMM8 => RD
2018
      // Cycles - P
2019
      {CONT, 16'b11000???????????} :
2020
         begin
2021
           ena_rd_low_byte  = 1'b1;
2022
           ena_rd_high_byte = 1'b1;
2023
 
2024
           alu_result    = rd_data - {8'b0, op_code[7:0]};
2025
           next_zero     = !(|alu_result);
2026
           next_negative = alu_result[15];
2027
           next_carry    = (!rd_data[7] && op_code[7]) || (!rd_data[7] && alu_result[7]) || (op_code[7] && alu_result[7]);
2028
           next_overflow = (rd_data[7] && !op_code[7] && !alu_result[7]) || (!rd_data[7] && op_code[7] && alu_result[7]);
2029
         end
2030
 
2031
      // Instruction = SUBH RD, #IMM8, Op Code =  1 1 0 0 1 RD IMM8
2032
      // SUB - Subtract without Carry
2033
      // RD - IMM8:$00 => RD
2034
      // Cycles - P
2035
      {CONT, 16'b11001???????????} :
2036
         begin
2037
           ena_rd_low_byte  = 1'b1;
2038
           ena_rd_high_byte = 1'b1;
2039
 
2040
           {next_carry, alu_result} = rd_data - {op_code[7:0], 8'b0};
2041
           next_zero     = !(|alu_result);
2042
           next_negative = alu_result[15];
2043
           next_overflow = (rd_data[15] && !op_code[7] && !alu_result[15]) || (!rd_data[15] && op_code[7] && alu_result[15]);
2044
         end
2045
 
2046
      // Instruction = CMPL RS, #IMM8, Op Code =  1 1 0 1 0 RS IMM8
2047
      // RS.L - IMM8 => NONE, only condition code flags get updated
2048
      // RS field == RD field
2049
      // Cycles - P
2050
      {CONT, 16'b11010???????????} :
2051
         begin
2052
 
2053
           alu_result    = {8'b0, rd_data[7:0] - op_code[7:0]};
2054
           next_zero     = !(|alu_result[7:0]);
2055
           next_negative = alu_result[7];
2056
           next_carry    = (!rd_data[7] && op_code[7]) || (!rd_data[7] && alu_result[7]) || (op_code[7] && alu_result[7]);
2057
           next_overflow = (rd_data[7] && !op_code[7] && !alu_result[7]) || (!rd_data[7] && op_code[7] && alu_result[7]);
2058
         end
2059
 
2060
      // Instruction = CPCH RS, #IMM8, Op Code =  1 1 0 1 1 RS IMM8
2061
      // RS.H - IMM8 - C => NONE, only condition code flags get updated
2062
      // RS field == RD field
2063
      // Cycles - P
2064
      {CONT, 16'b11011???????????} :
2065
         begin
2066
 
2067
           alu_result    = {rd_data[15:8], 8'b0} - {op_code[7:0], 8'b0} - {7'b0, carry_flag, 8'b0};
2068
           next_zero     = !(|alu_result[15:8]) && zero_flag;
2069
           next_negative = alu_result[15];
2070
           next_carry    = (!rd_data[15] && op_code[7]) || (!rd_data[15] && alu_result[15]) || (op_code[7] && alu_result[15]);
2071
           next_overflow = (rd_data[15] && !op_code[7] && !alu_result[15]) || (!rd_data[15] && op_code[7] && alu_result[15]);
2072
         end
2073
 
2074
      // Instruction = ADDL RD, #IMM8, Op Code =  1 1 1 0 0 RD IMM8
2075
      // ADD - ADD without carry
2076
      // RD + $00:IMM8 => RD
2077
      // Cycles - P
2078
      {CONT, 16'b11100???????????} :
2079
         begin
2080
           ena_rd_low_byte  = 1'b1;
2081
           ena_rd_high_byte = 1'b1;
2082
 
2083
           alu_result    = rd_data + {8'b0, op_code[7:0]};
2084
           next_zero     = !(|alu_result);
2085
           next_negative = alu_result[15];
2086
           next_carry    = (rd_data[7] && op_code[7]) || (rd_data[7] && !alu_result[7]) || (op_code[7] && !alu_result[7]);
2087
           next_overflow = (!rd_data[7] && !op_code[7] && alu_result[7]) || (rd_data[7] && op_code[7] && !alu_result[7]);
2088
         end
2089
 
2090
      // Instruction = ADDH RD, #IMM8, Op Code =  1 1 1 0 1 RD IMM8
2091
      // ADD - ADD without carry
2092
      // RD + IMM8:$00 => RD
2093
      // Cycles - P
2094
      {CONT, 16'b11101???????????} :
2095
         begin
2096
           ena_rd_low_byte  = 1'b1;
2097
           ena_rd_high_byte = 1'b1;
2098
 
2099
           {next_carry, alu_result} = rd_data + {op_code[7:0], 8'b0};
2100
           next_zero     = !(|alu_result);
2101
           next_negative = alu_result[15];
2102
           next_overflow = (rd_data[15] && op_code[7] && !alu_result[15]) || (!rd_data[15] && !op_code[7] && alu_result[15]);
2103
         end
2104
 
2105
      // Instruction = LDL RD, #IMM8, Op Code =  1 1 1 1 0 RD IMM8
2106
      // IMM8 => RD.L; $00 => RD.H, High Byte is cleared
2107
      // Cycles - P
2108
      {CONT, 16'b11110???????????} :
2109
         begin
2110
           ena_rd_low_byte  = 1'b1;
2111
           ena_rd_high_byte = 1'b1;
2112
 
2113
           alu_result    = {8'b0, op_code[7:0]};
2114
         end
2115
 
2116
      // Instruction = LDH RD, #IMM8, Op Code =  1 1 1 1 1 RD IMM8
2117
      // IMM8 => RD.H, Low Byte is unchanged
2118
      // Cycles - P
2119
      {CONT, 16'b11111???????????} :
2120
         begin
2121
           ena_rd_high_byte = 1'b1;
2122
 
2123
           alu_result    = {op_code[7:0], 8'b0};
2124
         end
2125
      default :
2126
        begin
2127 26 rehayes
          // synopsys translate_off
2128 2 rehayes
          $display("\nOP Code Error\n");
2129 26 rehayes
          // synopsys translate_on
2130 12 rehayes
          next_cpu_state   = DEBUG;
2131 40 rehayes
          pc_incr_mux      = 16'h0000;
2132
          next_pc          = pc_sum;
2133 12 rehayes
          load_next_inst   = 1'b0;
2134 17 rehayes
          op_code_error    = 1'b1;
2135 2 rehayes
        end
2136
    endcase
2137 40 rehayes
 
2138 2 rehayes
    end  // always
2139
 
2140
  xgate_barrel_shift barrel_shift(
2141
    // outputs
2142
    .shift_out( shift_out ),
2143
    .shift_rollover( shift_rollover ),
2144
    // inputs
2145
    .shift_left( shift_left ),
2146
    .shift_ammount( shift_ammount ),
2147
    .shift_in( shift_in ),
2148
    .shift_filler( shift_filler )
2149
  );
2150
 
2151
  // Three to Eight line decoder
2152
  always @*
2153 26 rehayes
    case (semaph_risc)  // synopsys parallel_case
2154 2 rehayes
      4'h0 : semap_risc_bit = 8'b0000_0001;
2155
      4'h1 : semap_risc_bit = 8'b0000_0010;
2156
      4'h2 : semap_risc_bit = 8'b0000_0100;
2157
      4'h3 : semap_risc_bit = 8'b0000_1000;
2158
      4'h4 : semap_risc_bit = 8'b0001_0000;
2159
      4'h5 : semap_risc_bit = 8'b0010_0000;
2160
      4'h6 : semap_risc_bit = 8'b0100_0000;
2161
      4'h7 : semap_risc_bit = 8'b1000_0000;
2162
    endcase
2163 12 rehayes
 
2164 2 rehayes
  assign semaph_stat = |risc_semap;
2165
 
2166 59 rehayes
  // Semaphore Bits
2167
  genvar sem_gen_count;
2168
  generate
2169
    for (sem_gen_count = 0; sem_gen_count < 8; sem_gen_count = sem_gen_count + 1)
2170
      begin:semaphore_
2171
        semaphore_bit bit(
2172
          // outputs
2173
          .host_status( host_semap[sem_gen_count] ),
2174
          .risc_status( risc_semap[sem_gen_count] ),
2175
          // inputs
2176
          .risc_clk( risc_clk ),
2177
          .async_rst_b( async_rst_b ),
2178
          .risc_bit_sel( semap_risc_bit[sem_gen_count] ),
2179
          .csem( clear_semaph ),
2180
          .ssem( set_semaph ),
2181
          .host_wrt( write_xgsem ),
2182
          .host_bit_mask( perif_data[sem_gen_count+8] ),
2183
          .host_bit( perif_data[sem_gen_count] )
2184
        );
2185
      end
2186
  endgenerate
2187 2 rehayes
 
2188
  endmodule  // xgate_inst_decode
2189
 
2190
// -----------------------------------------------------------------------------
2191
// -----------------------------------------------------------------------------
2192
// -----------------------------------------------------------------------------
2193
 
2194
module xgate_barrel_shift (
2195
  output reg [15:0] shift_out,
2196
  output reg        shift_rollover,
2197
 
2198
  input             shift_left,
2199
  input      [ 4:0] shift_ammount,
2200
  input      [15:0] shift_in,
2201
  input      [15:0] shift_filler
2202
  );
2203
 
2204
  always @*
2205 26 rehayes
    casez ({shift_left, shift_ammount})  // synopsys parallel_case
2206 2 rehayes
     // Start Right Shifts
2207
      6'b0_0_0000 :
2208
        begin
2209
          shift_out      = shift_in;
2210
          shift_rollover = 1'b0;
2211
        end
2212
      6'b0_0_0001 :
2213
        begin
2214
          shift_out      = {shift_filler[ 0], shift_in[15: 1]};
2215
          shift_rollover =  shift_in[ 0];
2216
        end
2217
      6'b0_0_0010 :
2218
        begin
2219
          shift_out      = {shift_filler[ 1:0], shift_in[15: 2]};
2220
          shift_rollover =  shift_in[ 1];
2221
        end
2222
      6'b0_0_0011 :
2223
        begin
2224
          shift_out      = {shift_filler[ 2:0], shift_in[15: 3]};
2225
          shift_rollover =  shift_in[ 2];
2226
        end
2227
      6'b0_0_0100 :
2228
        begin
2229
          shift_out      = {shift_filler[ 3:0], shift_in[15: 4]};
2230
          shift_rollover =  shift_in[ 3];
2231
        end
2232
      6'b0_0_0101 :
2233
        begin
2234
          shift_out      = {shift_filler[ 4:0], shift_in[15: 5]};
2235
          shift_rollover =  shift_in[ 4];
2236
        end
2237
      6'b0_0_0110 :
2238
        begin
2239
          shift_out      = {shift_filler[ 5:0], shift_in[15: 6]};
2240
          shift_rollover =  shift_in[ 5];
2241
        end
2242
      6'b0_0_0111 :
2243
        begin
2244
          shift_out      = {shift_filler[ 6:0], shift_in[15: 7]};
2245
          shift_rollover =  shift_in[ 6];
2246
        end
2247
      6'b0_0_1000 :
2248
        begin
2249
          shift_out      = {shift_filler[ 7:0], shift_in[15: 8]};
2250
          shift_rollover =  shift_in[ 7];
2251
        end
2252
      6'b0_0_1001 :
2253
        begin
2254
          shift_out      = {shift_filler[ 8:0], shift_in[15: 9]};
2255
          shift_rollover =  shift_in[ 8];
2256
        end
2257
      6'b0_0_1010 :
2258
        begin
2259
          shift_out      = {shift_filler[ 9:0], shift_in[15:10]};
2260
          shift_rollover =  shift_in[ 9];
2261
        end
2262
      6'b0_0_1011 :
2263
        begin
2264
          shift_out      = {shift_filler[10:0], shift_in[15:11]};
2265
          shift_rollover =  shift_in[10];
2266
        end
2267
      6'b0_0_1100 :
2268
        begin
2269
          shift_out      = {shift_filler[11:0], shift_in[15:12]};
2270
          shift_rollover =  shift_in[11];
2271
        end
2272
      6'b0_0_1101 :
2273
        begin
2274
          shift_out      = {shift_filler[12:0], shift_in[15:13]};
2275
          shift_rollover =  shift_in[12];
2276
        end
2277
      6'b0_0_1110 :
2278
        begin
2279
          shift_out      = {shift_filler[13:0], shift_in[15:14]};
2280
          shift_rollover =  shift_in[13];
2281
        end
2282
      6'b0_0_1111 :
2283
        begin
2284
          shift_out      = {shift_filler[14:0], shift_in[15]};
2285
          shift_rollover =  shift_in[14];
2286
        end
2287
      6'b0_1_???? :
2288
        begin
2289
          shift_out      = shift_filler[15:0];
2290
          shift_rollover = shift_in[15];
2291
        end
2292 12 rehayes
 
2293 2 rehayes
     // Start Left Shifts
2294 12 rehayes
 
2295 2 rehayes
      6'b1_0_0000 :
2296
        begin
2297
          shift_out      =  shift_in;
2298
          shift_rollover  = 1'b0;
2299
        end
2300
      6'b1_0_0001 :
2301
        begin
2302
          shift_out      = {shift_in[14:0], shift_filler[15]};
2303
          shift_rollover =  shift_in[15];
2304
        end
2305
      6'b1_0_0010 :
2306
        begin
2307
          shift_out      = {shift_in[13:0], shift_filler[15:14]};
2308
          shift_rollover =  shift_in[14];
2309
        end
2310
      6'b1_0_0011 :
2311
        begin
2312
          shift_out      = {shift_in[12:0], shift_filler[15:13]};
2313
          shift_rollover =  shift_in[13];
2314
        end
2315
      6'b1_0_0100 :
2316
        begin
2317
          shift_out      = {shift_in[11:0], shift_filler[15:12]};
2318
          shift_rollover =  shift_in[12];
2319
        end
2320
      6'b1_0_0101 :
2321
        begin
2322
          shift_out      = {shift_in[10:0], shift_filler[15:11]};
2323
          shift_rollover =  shift_in[11];
2324
        end
2325
      6'b1_0_0110 :
2326
        begin
2327
          shift_out      = {shift_in[ 9:0], shift_filler[15:10]};
2328
          shift_rollover =  shift_in[10];
2329
        end
2330
      6'b1_0_0111 :
2331
        begin
2332
          shift_out      = {shift_in[ 8:0], shift_filler[15: 9]};
2333
          shift_rollover =  shift_in[ 9];
2334
        end
2335
      6'b1_0_1000 :
2336
        begin
2337
          shift_out      = {shift_in[ 7:0], shift_filler[15: 8]};
2338
          shift_rollover =  shift_in[ 8];
2339
        end
2340
      6'b1_0_1001 :
2341
        begin
2342
          shift_out      = {shift_in[ 6:0], shift_filler[15: 7]};
2343
          shift_rollover =  shift_in[ 7];
2344
        end
2345
      6'b1_0_1010 :
2346
        begin
2347
          shift_out      = {shift_in[ 5:0], shift_filler[15: 6]};
2348
          shift_rollover =  shift_in[ 6];
2349
        end
2350
      6'b1_0_1011 :
2351
        begin
2352
          shift_out      = {shift_in[ 4:0], shift_filler[15: 5]};
2353
          shift_rollover =  shift_in[ 5];
2354
        end
2355
      6'b1_0_1100 :
2356
        begin
2357
          shift_out      = {shift_in[ 3:0], shift_filler[15 :4]};
2358
          shift_rollover =  shift_in[ 4];
2359
        end
2360
      6'b1_0_1101 :
2361
        begin
2362
          shift_out      = {shift_in[ 2:0], shift_filler[15: 3]};
2363
          shift_rollover =  shift_in[ 3];
2364
        end
2365
      6'b1_0_1110 :
2366
        begin
2367
          shift_out      = {shift_in[ 1:0], shift_filler[15: 2]};
2368
          shift_rollover =  shift_in[ 2];
2369
        end
2370
      6'b1_0_1111 :
2371
        begin
2372
          shift_out      = {shift_in[ 0], shift_filler[15: 1]};
2373
          shift_rollover =  shift_in[ 1];
2374
        end
2375
      6'b1_1_???? :
2376
        begin
2377
          shift_out      = shift_filler[15: 0];
2378
          shift_rollover = shift_in[ 0];
2379
        end
2380
    endcase
2381 12 rehayes
 
2382
 
2383 2 rehayes
endmodule  // xgate_barrel_shift
2384
 
2385
// -----------------------------------------------------------------------------
2386
// -----------------------------------------------------------------------------
2387
// -----------------------------------------------------------------------------
2388
 
2389
module semaphore_bit #(parameter NO_LOCK   = 2'b00,
2390
                       parameter RISC_LOCK = 2'b10,
2391 12 rehayes
                       parameter HOST_LOCK = 2'b11)
2392 2 rehayes
  (
2393
  output      host_status,   // Return status for Host processor
2394
  output      risc_status,   // Return Status for RISC processor
2395
 
2396
  input       risc_clk,      // Semaphore register clock
2397
  input       async_rst_b,   // Async reset signal
2398
  input       risc_bit_sel,  // Bit selected by RISC
2399
  input       csem,          // RISC Clear Semaphore Bit
2400
  input       ssem,          // RISC Set Semaphore Bit
2401
  input       host_wrt,      // Host write to the Semaphore Register
2402
  input       host_bit_mask, // Host mask bit written to the Semaphore bit
2403
  input       host_bit       // Host bit written to the Semaphore bit
2404
  );
2405
 
2406
  reg [1:0] next_semap_state;
2407
  reg [1:0] semap_state;
2408 12 rehayes
 
2409 2 rehayes
  assign host_status = semap_state == HOST_LOCK;
2410
  assign risc_status = ssem && risc_bit_sel && ((semap_state == RISC_LOCK) || (next_semap_state == RISC_LOCK));
2411
 
2412
  always @(posedge risc_clk or negedge async_rst_b)
2413
    if (!async_rst_b)
2414
      semap_state <= NO_LOCK;
2415
    else
2416
      semap_state <= next_semap_state;
2417
 
2418
  always @*
2419
    begin
2420
      case(semap_state)
2421 12 rehayes
        NO_LOCK:
2422
          begin
2423
            if (host_wrt && host_bit_mask && host_bit)
2424
              next_semap_state = HOST_LOCK;
2425
            else if (ssem && risc_bit_sel)
2426
              next_semap_state = RISC_LOCK;
2427
            else
2428
              next_semap_state = NO_LOCK;
2429
          end
2430
        RISC_LOCK:
2431
          begin
2432
            if (csem && risc_bit_sel)
2433
              next_semap_state = NO_LOCK;
2434 26 rehayes
            else
2435
              next_semap_state = RISC_LOCK;
2436
           end
2437 12 rehayes
        HOST_LOCK:
2438
          begin
2439
            if (host_wrt && host_bit_mask && !host_bit)
2440
              next_semap_state = NO_LOCK;
2441 26 rehayes
            else
2442
              next_semap_state = HOST_LOCK;
2443
           end
2444 12 rehayes
        default:
2445
          next_semap_state = NO_LOCK;
2446 2 rehayes
      endcase
2447
    end
2448 12 rehayes
 
2449 2 rehayes
endmodule  // semaphore_bit
2450
 
2451
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.