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

Subversion Repositories xgate

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

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

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

powered by: WebSVN 2.1.0

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