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

Subversion Repositories xgate

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

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

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

powered by: WebSVN 2.1.0

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