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

Subversion Repositories xgate

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

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

powered by: WebSVN 2.1.0

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