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

Subversion Repositories xgate

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

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

powered by: WebSVN 2.1.0

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