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

Subversion Repositories xgate

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

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

powered by: WebSVN 2.1.0

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