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

Subversion Repositories xgate

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

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

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

powered by: WebSVN 2.1.0

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