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

Subversion Repositories xgate

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

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

powered by: WebSVN 2.1.0

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