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

Subversion Repositories xgate

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

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

powered by: WebSVN 2.1.0

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