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

Subversion Repositories xgate

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

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

powered by: WebSVN 2.1.0

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