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

Subversion Repositories xgate

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

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

powered by: WebSVN 2.1.0

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