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

Subversion Repositories xgate

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

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

powered by: WebSVN 2.1.0

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