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

Subversion Repositories xgate

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

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

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

powered by: WebSVN 2.1.0

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