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

Subversion Repositories xgate

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

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

powered by: WebSVN 2.1.0

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