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

Subversion Repositories y80e

[/] [y80e/] [trunk/] [rtl/] [datapath.v] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 bsa
/*******************************************************************************************/
2
/**                                                                                       **/
3
/** COPYRIGHT (C) 2011, SYSTEMYDE INTERNATIONAL CORPORATION, ALL RIGHTS RESERVED          **/
4
/**                                                                                       **/
5
/** data path module                                                  Rev 0.0  08/22/2010 **/
6
/**                                                                                       **/
7
/*******************************************************************************************/
8
module datapath (addr_reg_in, carry_bit, dmar_reg, dout_io_reg, dout_mem_reg, inst_reg,
9
                 intr_reg, page_reg, par_bit, sign_bit, tflg_reg, vector_int, xhlt_reg,
10
                 zero_bit, add_sel, alua_sel, alub_sel, aluop_sel, clearb, clkc, cflg_en,
11
                 data_in, di_ctl, dma_req, do_ctl, ex_af_pls, ex_bank_pls, ex_dehl_inst,
12
                 hflg_ctl, ief_ctl, imd_ctl, int_req, ivec_rd, ld_ctrl, ld_inst, ld_page,
13
                 nflg_ctl, nmi_req, page_sel, pc_sel, pflg_ctl, resetb, sflg_en, tflg_ctl,
14
                 wait_st, wr_addr, zflg_en);
15
 
16
  input         cflg_en;       /* carry flag control                                       */
17
  input         clearb;        /* master (testing) reset                                   */
18
  input         clkc;          /* main cpu clock                                           */
19
  input         dma_req;       /* dma request                                              */
20
  input         ex_af_pls;     /* exchange af,af'                                          */
21
  input         ex_bank_pls;   /* exchange register bank                                   */
22
  input         ex_dehl_inst;  /* exchange de,hl                                           */
23
  input         int_req;       /* interrupt request                                        */
24
  input         ivec_rd;       /* interrupt vector enable                                  */
25
  input         ld_ctrl;       /* load control register                                    */
26
  input         ld_inst;       /* load instruction register                                */
27
  input         ld_page;       /* load page register                                       */
28
  input         nmi_req;       /* nmi request                                              */
29
  input         resetb;        /* internal (user) reset                                    */
30
  input         sflg_en;       /* sign flag control                                        */
31
  input         wait_st;       /* wait state identifier                                    */
32
  input         zflg_en;       /* zero flag control                                        */
33
  input   [3:0] page_sel;      /* instruction decode "page" control                        */
34
  input   [7:0] data_in;       /* read data bus                                            */
35
  input  [`ADCTL_IDX:0] add_sel;     /* address output mux control                         */
36
  input   [`ALUA_IDX:0] alua_sel;    /* alu input a mux control                            */
37
  input   [`ALUB_IDX:0] alub_sel;    /* alu input b mux control                            */
38
  input  [`ALUOP_IDX:0] aluop_sel;   /* alu operation control                              */
39
  input     [`DI_IDX:0] di_ctl;      /* data input control                                 */
40
  input     [`DO_IDX:0] do_ctl;      /* data output control                                */
41
  input   [`HFLG_IDX:0] hflg_ctl;    /* half-carry flag control                            */
42
  input    [`IEF_IDX:0] ief_ctl;     /* interrupt enable control                           */
43
  input    [`IMD_IDX:0] imd_ctl;     /* interrupt mode control                             */
44
  input   [`NFLG_IDX:0] nflg_ctl;    /* negate flag control                                */
45
  input  [`PCCTL_IDX:0] pc_sel;      /* program counter source control                     */
46
  input   [`PFLG_IDX:0] pflg_ctl;    /* parity/overflow flag control                       */
47
  input   [`TFLG_IDX:0] tflg_ctl;    /* temp flag control                                  */
48
  input   [`WREG_IDX:0] wr_addr;     /* register write address bus                         */
49
  output        carry_bit;     /* carry flag                                               */
50
  output        dmar_reg;      /* latched dma request                                      */
51
  output        intr_reg;      /* latched interrupt request                                */
52
  output        par_bit;       /* parity flag                                              */
53
  output        sign_bit;      /* sign flag                                                */
54
  output        tflg_reg;      /* temporary flag                                           */
55
  output        vector_int;    /* int vector enable                                        */
56
  output        xhlt_reg;      /* halt exit                                                */
57
  output        zero_bit;      /* zero flag                                                */
58
  output  [3:0] page_reg;      /* instruction decode "page"                                */
59
  output  [7:0] inst_reg;      /* instruction register                                     */
60
  output  [7:0] dout_io_reg;   /* i/o write data bus                                       */
61
  output  [7:0] dout_mem_reg;  /* memory write data bus                                    */
62
  output [15:0] addr_reg_in;   /* processor address bus                                    */
63
 
64
  /*****************************************************************************************/
65
  /*                                                                                       */
66
  /* signal declarations                                                                   */
67
  /*                                                                                       */
68
  /*****************************************************************************************/
69
  wire         adder_c;                                    /* math carry                   */
70
  wire         adder_hc;                                   /* math half-carry              */
71
  wire         adder_ov;                                   /* math overflow result         */
72
  wire         alu_carry;                                  /* final carry                  */
73
  wire         alu_hcar;                                   /* final half-carry             */
74
  wire         alu_neg;                                    /* final negate                 */
75
  wire         alu_one;                                    /* final one                    */
76
  wire         alu_sign;                                   /* final sign                   */
77
  wire         alu_zero;                                   /* final zero                   */
78
  wire         bit7, bit6, bit5, bit4;                     /* bit decode                   */
79
  wire         bit3, bit2, bit1, bit0;
80
  wire         carry_bit;                                  /* carry flag                   */
81
  wire         carry_daa;                                  /* daa carry                    */
82
  wire         cry_nxt;                                    /* combined carry               */
83
  wire         daa_l1, daa_l2, daa_l3, daa_l4;             /* decimal adjust               */
84
  wire         daa_l5, daa_h1, daa_h2, daa_h3;
85
  wire         daa_h4, daa_h5, daa_h6, daa_h7;
86
  wire         daa1, daa2, daa3, daa4, daa5;
87
  wire         daa6, daa7;
88
  wire         hcar_nxt;                                   /* combined half-carry          */
89
  wire         hi_byte;                                    /* replicate data byte          */
90
  wire         ld_m_aa, ld_m_ff, ld_m_bb, ld_m_cc;         /* register loads               */
91
  wire         ld_m_dd, ld_m_ee, ld_m_hh, ld_m_ll;
92
  wire         ld_a_aa, ld_a_ff, ld_a_bb, ld_a_cc;
93
  wire         ld_a_dd, ld_a_ee, ld_a_hh, ld_a_ll;
94
  wire         ld_sp,   ld_ix,   ld_iy;
95
  wire         ld_ii,   ld_rr,   ld_tmp;
96
  wire         ld_dout_io, ld_dout_mem;                    /* load data out                */
97
  wire         ld_flag;                                    /* load flags                   */
98
  wire         ld_regf;                                    /* load register file           */
99
  wire         ld_tflg;                                    /* load temp flag               */
100
  wire         logic_c;                                    /* logic carry                  */
101
  wire         logic_hc;                                   /* logic half-carry             */
102
  wire         one_nxt;                                    /* combined one                 */
103
  wire         par_bit;                                    /* parity flag                  */
104
  wire         par_nxt;                                    /* combined parity              */
105
  wire         shft_c;                                     /* shift carry                  */
106
  wire         sign_bit;                                   /* sign flag                    */
107
  wire         sign_nxt;                                   /* combined sign                */
108
  wire         vector_int;                                 /* int vector enable            */
109
  wire         zero_bit;                                   /* zero flag                    */
110
  wire         zero_nxt;                                   /* combined zero                */
111
  wire   [7:0] bit_mask;                                   /* mask for bit inst            */
112
  wire   [7:0] daa_out;                                    /* daa result                   */
113
  wire   [7:0] ff_reg_in;                                  /* register input               */
114
  wire   [7:0] aa_reg_out, ff_reg_out;                     /* register outputs             */
115
  wire   [7:0] new_flags;                                  /* new flag byte                */
116
  wire   [7:0] rst_addr;                                   /* restart address              */
117
  wire   [7:0] shft_out;                                   /* shift result                 */
118
  wire  [15:8] bsign_ext;                                  /* address alu b sign extend    */
119
  wire  [15:0] adda_in, addb_in;                           /* address alu inputs           */
120
  wire  [15:0] adder_out;                                  /* math result                  */
121
  wire  [15:0] addr_alu, addr_hl, addr_pc, addr_sp;        /* address mux terms            */
122
  wire  [15:0] addr_reg_in;                                /* address register input       */
123
  wire  [15:0] alua_in, alub_in;                           /* alu inputs                   */
124
  wire  [15:0] data_bus;                                   /* alu output                   */
125
  wire  [15:0] de_reg_in;                                  /* register inputs              */
126
  wire  [15:0] af_reg_out, bc_reg_out;                     /* register outputs             */
127
  wire  [15:0] de_reg_out, hl_reg_out;
128
  wire  [15:0] logic_out;                                  /* logic result                 */
129
 
130
  reg          alt_af_reg, alt_bnk_reg;                    /* main/alt select              */
131
  reg          alu_ovflo;                                  /* final ov                     */
132
  reg          daa_sel, daa_op;                            /* daa operation                */
133
  reg          decr_sel, decr_op;                          /* decrement operation          */
134
  reg          dmar_reg;                                   /* latched dma request          */
135
  reg          ex_dehl_reg;                                /* special exchange             */
136
  reg          ief1_reg;                                   /* int enable flag 1            */
137
  reg          ief2_reg;                                   /* int enable flag 2            */
138
  reg          imd1_reg;                                   /* int mode 1                   */
139
  reg          imd2_reg;                                   /* int mode 2                   */
140
  reg          intr_reg;                                   /* latched int req              */
141
  reg          ld_dmar, ld_intr;                           /* sample int/dma               */
142
  reg          ld_pc;                                      /* load pc                      */
143
  reg          nmi_hld;                                    /* nmi edge tracker             */
144
  reg          nmi_reg;                                    /* latched nmi req              */
145
  reg          tflg_nxt, tflg_reg;                         /* temp flag                    */
146
  reg          valid_dma;                                  /* valid dma request            */
147
  reg          valid_int, valid_nmi, valid_xhlt;           /* valid int request            */
148
  reg          word_sel, word_op;                          /* 16-bit operation             */
149
  reg          xhlt_reg;                                   /* halt exit                    */
150
  reg    [3:0] page_reg /* synthesis syn_preserve=1 */;
151
  reg    [7:0] inst_reg;                                   /* instruction register         */
152
  reg    [7:0] m_aa_reg, m_ff_reg, m_bb_reg, m_cc_reg;     /* individual registers         */
153
  reg    [7:0] m_dd_reg, m_ee_reg, m_hh_reg, m_ll_reg;
154
  reg    [7:0] a_aa_reg, a_ff_reg, a_bb_reg, a_cc_reg;
155
  reg    [7:0] a_dd_reg, a_ee_reg, a_hh_reg, a_ll_reg;
156
  reg    [7:0] ii_reg, rr_reg;
157
  reg    [7:0] din0_reg, din1_reg;                         /* data input registers         */
158
  reg    [7:0] dout_io_reg, dout_mem_reg;                  /* data output registers        */
159
  reg   [15:0] adda_out;                                   /* address alu out              */
160
  reg   [15:0] int_addr;                                   /* interrupt address            */
161
  reg   [15:0] ix_reg, iy_reg;                             /* index registers              */
162
  reg   [15:0] pc_reg;                                     /* program counter              */
163
  reg   [15:0] sp_reg;                                     /* stack pointer                */
164
  reg   [15:0] tmp_reg;                                    /* temporary register           */
165
  reg [`ADCTL_IDX:0] addsel_reg  /* synthesis syn_preserve=1 */;
166
  reg  [`ALUA_IDX:0] alua_reg    /* synthesis syn_preserve=1 */;
167
  reg  [`ALUB_IDX:0] alub_reg    /* synthesis syn_preserve=1 */;
168
  reg [`ALUOP_IDX:0] aluop_reg   /* synthesis syn_preserve=1 */;
169
 
170
  /*****************************************************************************************/
171
  /*                                                                                       */
172
  /* input synchronization                                                                 */
173
  /*                                                                                       */
174
  /*****************************************************************************************/
175
  always @ (posedge clkc or negedge resetb) begin
176
    if (!resetb) begin
177
      nmi_hld    <= 1'b0;
178
      valid_dma  <= 1'b0;
179
      valid_int  <= 1'b0;
180
      valid_nmi  <= 1'b0;
181
      valid_xhlt <= 1'b0;
182
      end
183
    else begin
184
      nmi_hld    <= (nmi_req && !valid_nmi) || (!(ivec_rd && nmi_reg) && nmi_hld);
185
      valid_dma  <= dma_req;
186
      valid_int  <= nmi_req || nmi_hld || ((&ief_ctl[1:0] || ief1_reg) && int_req);
187
      valid_nmi  <= nmi_req || nmi_hld;
188
      valid_xhlt <= !dma_req && (nmi_req || nmi_hld || (ief1_reg && int_req));
189
      end
190
    end
191
 
192
  /*****************************************************************************************/
193
  /*                                                                                       */
194
  /* interrupt mode and enables                                                            */
195
  /*                                                                                       */
196
  /*****************************************************************************************/
197
  always @ (posedge clkc or negedge resetb) begin
198
    if (!resetb) begin
199
      ief1_reg   <= 1'b0;
200
      ief2_reg   <= 1'b0;
201
      imd1_reg   <= 1'b0;
202
      imd2_reg   <= 1'b0;
203
      end
204
    else begin
205
      if (|ief_ctl[2:1]) ief1_reg <= (ief_ctl[1]) ? ief_ctl[0] : (ief_ctl[0] && ief2_reg);
206
      if (|ief_ctl[2:1]) ief2_reg <= (ief_ctl[1]) ? ief_ctl[0] :
207
                                     (ief_ctl[0]) ? ief2_reg   : (nmi_reg && ief1_reg);
208
      if (|imd_ctl)      imd1_reg <= imd_ctl[1] && !imd_ctl[0];
209
      if (|imd_ctl)      imd2_reg <= &imd_ctl;
210
      end
211
    end
212
 
213
  assign vector_int = imd2_reg && !nmi_reg;
214
 
215
  /*****************************************************************************************/
216
  /*                                                                                       */
217
  /* interrupt pending                                                                     */
218
  /*                                                                                       */
219
  /*****************************************************************************************/
220
  always @ (pc_sel or wait_st) begin
221
    case (pc_sel)
222
      `PC_DMA,                                             /* dma xfer dma sample          */
223
      `PC_INT:  ld_dmar = 1'b1;                            /* block inst dma sample        */
224
      `PC_NILD: ld_dmar = !wait_st;                        /* inst end dma sample          */
225
      default:  ld_dmar = 1'b0;
226
      endcase
227
    end
228
 
229
  always @ (pc_sel or wait_st) begin
230
    case (pc_sel)
231
      `PC_INT:  ld_intr = 1'b1;                            /* block inst int sample        */
232
      `PC_NILD: ld_intr = !wait_st;                        /* inst end int sample          */
233
      default:  ld_intr = 1'b0;
234
      endcase
235
    end
236
 
237
  always @ (posedge clkc or negedge resetb) begin
238
    if (!resetb) begin
239
      dmar_reg <= 1'b0;
240
      intr_reg <= 1'b0;
241
      nmi_reg  <= 1'b0;
242
      xhlt_reg <= 1'b0;
243
      end
244
    else begin
245
      if (ld_dmar) dmar_reg <= valid_dma;
246
      if (ld_intr) intr_reg <= !valid_dma && (valid_nmi || (ief1_reg && valid_int));
247
      if (ld_intr) nmi_reg  <= !valid_dma &&  valid_nmi;
248
      if (ld_intr) xhlt_reg <= !valid_dma &&  valid_xhlt;
249
      end
250
    end
251
 
252
  /*****************************************************************************************/
253
  /*                                                                                       */
254
  /* register control                                                                      */
255
  /*                                                                                       */
256
  /*****************************************************************************************/
257
  always @ (pc_sel or dmar_reg or intr_reg or valid_dma or valid_int or wait_st) begin
258
    case (pc_sel)
259
      `PC_LD:    ld_pc = !wait_st;                         /* load PC unconditionally      */
260
      `PC_NILD:  ld_pc = !((ief1_reg && valid_int) || valid_nmi || valid_dma) && !wait_st;
261
      `PC_NILD2: ld_pc = !(intr_reg || dmar_reg) && !wait_st;     /* if no latched int     */
262
      default:   ld_pc = 1'b0;
263
      endcase
264
    end
265
 
266
  always @ (posedge clkc or negedge resetb) begin
267
    if (!resetb) begin
268
      alt_af_reg  <= 1'b0;
269
      alt_bnk_reg <= 1'b0;
270
      ex_dehl_reg <= 1'b0;
271
      end
272
    else begin
273
      alt_af_reg  <= ex_af_pls   ^ alt_af_reg;
274
      alt_bnk_reg <= ex_bank_pls ^ alt_bnk_reg;
275
      ex_dehl_reg <= ex_dehl_inst && ld_ctrl;
276
      end
277
    end
278
 
279
  assign ld_flag = (sflg_en || zflg_en || |hflg_ctl || |pflg_ctl || |nflg_ctl ||
280
                    cflg_en) && !wait_st;
281
  assign ld_regf = wr_addr[`WR_REG] && !wait_st;
282
 
283
  /*****************************************************************************************/
284
  /*                                                                                       */
285
  /* cpu register interface                                                                */
286
  /*                                                                                       */
287
  /*****************************************************************************************/
288
  assign ff_reg_in    = (ld_flag)     ? new_flags : data_bus[7:0];
289
  assign de_reg_in    = (ex_dehl_reg) ? hl_reg_out : data_bus;
290
 
291
  assign ld_m_aa =   ld_regf && wr_addr[`WR_AA] && !alt_af_reg;
292
  assign ld_m_ff = ((ld_regf && wr_addr[`WR_FF]) || ld_flag) && !alt_af_reg;
293
  assign ld_m_bb =   ld_regf && wr_addr[`WR_BB] && !alt_bnk_reg;
294
  assign ld_m_cc =   ld_regf && wr_addr[`WR_CC] && !alt_bnk_reg;
295
  assign ld_m_dd =   ld_regf && wr_addr[`WR_DD] && !alt_bnk_reg;
296
  assign ld_m_ee =   ld_regf && wr_addr[`WR_EE] && !alt_bnk_reg;
297
  assign ld_m_hh =   ld_regf && wr_addr[`WR_HH] && !alt_bnk_reg;
298
  assign ld_m_ll =   ld_regf && wr_addr[`WR_LL] && !alt_bnk_reg;
299
  assign ld_a_aa =   ld_regf && wr_addr[`WR_AA] &&  alt_af_reg;
300
  assign ld_a_ff = ((ld_regf && wr_addr[`WR_FF]) || ld_flag) &&  alt_af_reg;
301
  assign ld_a_bb =   ld_regf && wr_addr[`WR_BB] &&  alt_bnk_reg;
302
  assign ld_a_cc =   ld_regf && wr_addr[`WR_CC] &&  alt_bnk_reg;
303
  assign ld_a_dd =   ld_regf && wr_addr[`WR_DD] &&  alt_bnk_reg;
304
  assign ld_a_ee =   ld_regf && wr_addr[`WR_EE] &&  alt_bnk_reg;
305
  assign ld_a_hh =   ld_regf && wr_addr[`WR_HH] &&  alt_bnk_reg;
306
  assign ld_a_ll =   ld_regf && wr_addr[`WR_LL] &&  alt_bnk_reg;
307
  assign ld_sp   =   ld_regf && wr_addr[`WR_SP];
308
  assign ld_ix   =   ld_regf && wr_addr[`WR_IX];
309
  assign ld_iy   =   ld_regf && wr_addr[`WR_IY];
310
  assign ld_ii   =   ld_regf && wr_addr[`WR_II];
311
  assign ld_rr   =   ld_regf && wr_addr[`WR_RR];
312
  assign ld_tmp  =   ld_regf && wr_addr[`WR_TMP];
313
 
314
  assign af_reg_out = (alt_af_reg)  ? {a_aa_reg, a_ff_reg} : {m_aa_reg, m_ff_reg};
315
  assign bc_reg_out = (alt_bnk_reg) ? {a_bb_reg, a_cc_reg} : {m_bb_reg, m_cc_reg};
316
  assign de_reg_out = (alt_bnk_reg) ? {a_dd_reg, a_ee_reg} : {m_dd_reg, m_ee_reg};
317
  assign hl_reg_out = (alt_bnk_reg) ? {a_hh_reg, a_ll_reg} : {m_hh_reg, m_ll_reg};
318
  assign aa_reg_out = af_reg_out[15:8];
319
  assign ff_reg_out = af_reg_out[7:0];
320
  assign carry_bit  = af_reg_out[0];
321
  assign par_bit    = af_reg_out[2];
322
  assign sign_bit   = af_reg_out[7];
323
  assign zero_bit   = af_reg_out[6];
324
  assign hi_byte    = (wr_addr[`WR_AA] && !wr_addr[`WR_FF]) ||
325
                      (wr_addr[`WR_BB] && !wr_addr[`WR_CC]) ||
326
                      (wr_addr[`WR_DD] && !wr_addr[`WR_EE]) ||
327
                      (wr_addr[`WR_HH] && !wr_addr[`WR_LL]) ||
328
                       wr_addr[`WR_II] || wr_addr[`WR_RR];
329
 
330
  /*****************************************************************************************/
331
  /*                                                                                       */
332
  /* cpu registers                                                                         */
333
  /*                                                                                       */
334
  /*****************************************************************************************/
335
  always @ (posedge clkc or negedge clearb) begin
336
    if (!clearb) begin
337
      m_aa_reg <= 8'h00;
338
      m_ff_reg <= 8'h00;
339
      m_bb_reg <= 8'h00;
340
      m_cc_reg <= 8'h00;
341
      m_dd_reg <= 8'h00;
342
      m_ee_reg <= 8'h00;
343
      m_hh_reg <= 8'h00;
344
      m_ll_reg <= 8'h00;
345
      a_aa_reg <= 8'h00;
346
      a_ff_reg <= 8'h00;
347
      a_bb_reg <= 8'h00;
348
      a_cc_reg <= 8'h00;
349
      a_dd_reg <= 8'h00;
350
      a_ee_reg <= 8'h00;
351
      a_hh_reg <= 8'h00;
352
      a_ll_reg <= 8'h00;
353
      ix_reg   <= 16'h0000;
354
      iy_reg   <= 16'h0000;
355
      end
356
    else begin
357
      if (ld_m_aa) m_aa_reg <= data_bus[15:8];
358
      if (ld_m_ff) m_ff_reg <= ff_reg_in;
359
      if (ld_m_bb) m_bb_reg <= data_bus[15:8];
360
      if (ld_m_cc) m_cc_reg <= data_bus[7:0];
361
      if (ld_m_dd) m_dd_reg <= de_reg_in[15:8];
362
      if (ld_m_ee) m_ee_reg <= de_reg_in[7:0];
363
      if (ld_m_hh) m_hh_reg <= data_bus[15:8];
364
      if (ld_m_ll) m_ll_reg <= data_bus[7:0];
365
      if (ld_a_aa) a_aa_reg <= data_bus[15:8];
366
      if (ld_a_ff) a_ff_reg <= ff_reg_in;
367
      if (ld_a_bb) a_bb_reg <= data_bus[15:8];
368
      if (ld_a_cc) a_cc_reg <= data_bus[7:0];
369
      if (ld_a_dd) a_dd_reg <= de_reg_in[15:8];
370
      if (ld_a_ee) a_ee_reg <= de_reg_in[7:0];
371
      if (ld_a_hh) a_hh_reg <= data_bus[15:8];
372
      if (ld_a_ll) a_ll_reg <= data_bus[7:0];
373
      if (ld_ix)   ix_reg   <= data_bus;
374
      if (ld_iy)   iy_reg   <= data_bus;
375
      end
376
    end
377
 
378
  always @ (posedge clkc or negedge resetb) begin
379
    if (!resetb) begin
380
      ii_reg  <= 8'h00;
381
      pc_reg  <= 16'h0000;
382
      rr_reg  <= 8'h00;
383
      sp_reg  <= 16'h0000;
384
      tmp_reg <= 16'h0000;
385
      end
386
    else begin
387
      if (ld_ii)  ii_reg  <= data_bus[15:8];
388
      if (ld_pc)  pc_reg  <= data_bus;
389
      if (ld_rr)  rr_reg  <= data_bus[15:8];
390
      if (ld_sp)  sp_reg  <= data_bus;
391
      if (ld_tmp) tmp_reg <= (ivec_rd) ? {ii_reg, data_in} : data_bus;
392
      end
393
    end
394
 
395
  /*****************************************************************************************/
396
  /*                                                                                       */
397
  /* temporary flag                                                                        */
398
  /*                                                                                       */
399
  /*****************************************************************************************/
400
  assign ld_tflg = |tflg_ctl && !wait_st;
401
 
402
  always @ (tflg_ctl or alu_one or alu_zero or ff_reg_out) begin
403
    casex (tflg_ctl)
404
      `TFLG_1:  tflg_nxt = alu_one;                        /* blk set if done (next xfr)   */
405
      `TFLG_Z:  tflg_nxt = alu_zero;                       /* blk set if done (this xfr)   */
406
      `TFLG_B:  tflg_nxt = alu_zero || !ff_reg_out[2];     /* blk cp set if done or match  */
407
      default:  tflg_nxt = 1'b0;
408
      endcase
409
    end
410
 
411
  always @ (posedge clkc or negedge resetb) begin
412
    if      (!resetb) tflg_reg <= 1'b0;
413
    else if (ld_tflg) tflg_reg <= tflg_nxt;
414
    end
415
 
416
  /*****************************************************************************************/
417
  /*                                                                                       */
418
  /* data input and data output registers                                                  */
419
  /*                                                                                       */
420
  /*****************************************************************************************/
421
  assign ld_dout_io   = do_ctl[1] && !wait_st;
422
  assign ld_dout_mem  = do_ctl[2] && !wait_st;
423
 
424
  always @ (posedge clkc or negedge resetb) begin
425
    if (!resetb) begin
426
      din0_reg     <= 8'h00;
427
      din1_reg     <= 8'h00;
428
      dout_io_reg  <= 8'h00;
429
      dout_mem_reg <= 8'h00;
430
      end
431
    else begin
432
      if (di_ctl[0])   din0_reg     <= data_in;
433
      if (di_ctl[1])   din1_reg     <= data_in;
434
      if (ld_dout_io)  dout_io_reg  <= data_bus[7:0];
435
      if (ld_dout_mem) dout_mem_reg <= (do_ctl[0]) ? data_bus[15:8] : data_bus[7:0];
436
      end
437
    end
438
 
439
  /*****************************************************************************************/
440
  /*                                                                                       */
441
  /* instruction and page registers                                                        */
442
  /*                                                                                       */
443
  /*****************************************************************************************/
444
  always @ (posedge clkc or negedge resetb) begin
445
    if      (!resetb) inst_reg <= 8'h00;
446
    else if (ld_inst) inst_reg <= data_in;
447
    end
448
 
449
  always @ (posedge clkc or negedge resetb) begin
450
    if                 (!resetb) page_reg <= 4'b0000;
451
    else if (ld_page && ld_ctrl) page_reg <= page_sel;
452
    end
453
 
454
  /*****************************************************************************************/
455
  /*                                                                                       */
456
  /* alu control pipeline registers                                                        */
457
  /*                                                                                       */
458
  /*****************************************************************************************/
459
  always @ (aluop_sel) begin
460
    case (aluop_sel) //synopsys parallel_case
461
      `ALUOP_DAA:  daa_sel = 1'b1;
462
      default:     daa_sel = 1'b0;
463
      endcase
464
    end
465
 
466
  always @ (aluop_sel) begin
467
    case (aluop_sel) //synopsys parallel_case
468
      `ALUOP_BDEC: decr_sel = 1'b1;
469
      default:     decr_sel = 1'b0;
470
      endcase
471
    end
472
 
473
  always @ (aluop_sel) begin
474
    case (aluop_sel) //synopsys parallel_case
475
      `ALUOP_ADC,
476
      `ALUOP_ADD,
477
      `ALUOP_PASS,
478
      `ALUOP_SBC,
479
      `ALUOP_SUB:  word_sel = 1'b1;
480
      default:     word_sel = 1'b0;
481
      endcase
482
    end
483
 
484
  always @ (posedge clkc or negedge resetb) begin
485
    if (!resetb) begin
486
      addsel_reg <= `ADD_RSTVAL;
487
      alua_reg   <= `ALUA_RSTVAL;
488
      alub_reg   <= `ALUB_RSTVAL;
489
      aluop_reg  <= `ALUOP_RSTVAL;
490
      daa_op     <= 1'b0;
491
      decr_op    <= 1'b0;
492
      word_op    <= 1'b0;
493
      end
494
    else if (ld_ctrl) begin
495
      addsel_reg <= add_sel;
496
      alua_reg   <= alua_sel;
497
      alub_reg   <= alub_sel;
498
      aluop_reg  <= aluop_sel;
499
      daa_op     <= daa_sel;
500
      decr_op    <= decr_sel;
501
      word_op    <= word_sel;
502
      end
503
    end
504
 
505
  /*****************************************************************************************/
506
  /*                                                                                       */
507
  /* bit manipulation constant generator                                                   */
508
  /*                                                                                       */
509
  /*****************************************************************************************/
510
  assign bit7     = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b111);
511
  assign bit6     = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b110);
512
  assign bit5     = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b101);
513
  assign bit4     = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b100);
514
  assign bit3     = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b011);
515
  assign bit2     = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b010);
516
  assign bit1     = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b001);
517
  assign bit0     = (inst_reg[7] && !inst_reg[6]) ^ (inst_reg[5:3] == 3'b000);
518
  assign bit_mask = {bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0};
519
 
520
  /*****************************************************************************************/
521
  /*                                                                                       */
522
  /* decimal adjust accumulator constant generator                                         */
523
  /*                                                                                       */
524
  /*****************************************************************************************/
525
  assign daa_l1 = !ff_reg_out[1] && !ff_reg_out[4] &&
526
                  (!aa_reg_out[3] || (aa_reg_out[3] && !aa_reg_out[2] && !aa_reg_out[1]));
527
  assign daa_l2 = !ff_reg_out[1] && !ff_reg_out[4] &&
528
                  (aa_reg_out[3] && (aa_reg_out[2] || aa_reg_out[1]));
529
  assign daa_l3 = !ff_reg_out[1] &&  ff_reg_out[4] && (!aa_reg_out[3] && !aa_reg_out[2]);
530
  assign daa_l4 =  ff_reg_out[1] && !ff_reg_out[4] &&
531
                  (!aa_reg_out[3] || (aa_reg_out[3] && !aa_reg_out[2] && !aa_reg_out[1]));
532
  assign daa_l5 =  ff_reg_out[1] &&  ff_reg_out[4] &&
533
                  ((!aa_reg_out[3] && aa_reg_out[2] && aa_reg_out[1]) || aa_reg_out[3]);
534
  assign daa_h1 = !ff_reg_out[0] && (aa_reg_out[7] && (aa_reg_out[6] || aa_reg_out[5]));
535
  assign daa_h2 =  ff_reg_out[0] &&
536
                  (!aa_reg_out[7] && !aa_reg_out[6] && (!aa_reg_out[5] || !aa_reg_out[4]));
537
  assign daa_h3 = !ff_reg_out[0] &&
538
                  (aa_reg_out[7] && (aa_reg_out[6] || aa_reg_out[5] || aa_reg_out[4]));
539
  assign daa_h4 =  ff_reg_out[0] && (!aa_reg_out[7] && !aa_reg_out[6]);
540
  assign daa_h5 =  ff_reg_out[0] &&
541
                  ((aa_reg_out[6] && aa_reg_out[5] && aa_reg_out[4]) || aa_reg_out[7]);
542
  assign daa_h6 = !ff_reg_out[0] &&
543
                  ((!aa_reg_out[6] && !aa_reg_out[5] && !aa_reg_out[4]) || !aa_reg_out[7]);
544
  assign daa_h7 =  ff_reg_out[0] && ((aa_reg_out[6] && aa_reg_out[5]) || aa_reg_out[7]);
545
 
546
  assign daa1   = daa_l2 || daa_l3 || daa_l5;
547
  assign daa2   = daa_l2 || daa_l3;
548
  assign daa3   = daa_l5;
549
  assign daa4   = daa_l5 && (daa_h6 || daa_h7);
550
  assign daa5   = (daa_l1 && (daa_h1 || daa_h2)) || (daa_l2 && (daa_h2 || daa_h3)) ||
551
                  (daa_l3 && (daa_h1 || daa_h4)) || (daa_l4 && daa_h5) ||
552
                  (daa_l5 && daa_h6);
553
  assign daa6   = (daa_l1 && (daa_h1 || daa_h2)) || (daa_l2 && (daa_h2 || daa_h3)) ||
554
                  (daa_l3 && (daa_h1 || daa_h4)) || (daa_l5 && daa_h6);
555
  assign daa7   = (daa_l4 && daa_h5) || (daa_l5 && (daa_h6 || daa_h7));
556
 
557
  assign daa_out   = {daa7, daa6, daa5, daa4, daa3, daa2, daa1, 1'b0};
558
  assign carry_daa = (daa_l1 && (daa_h1 || daa_h2)) || (daa_l2 && (daa_h2 || daa_h3)) ||
559
                     (daa_l3 && (daa_h1 || daa_h4)) || (daa_l4 && daa_h5) ||
560
                     (daa_l5 && daa_h7);
561
 
562
  /*****************************************************************************************/
563
  /*                                                                                       */
564
  /* interrupt/restart address generator                                                   */
565
  /*                                                                                       */
566
  /*****************************************************************************************/
567
  assign rst_addr = {2'b00, inst_reg[5:3], 3'b000};
568
 
569
  always @ (nmi_reg or imd2_reg or imd1_reg or din0_reg or din1_reg) begin
570
    casex ({nmi_reg, imd2_reg, imd1_reg})
571
      3'b001:  int_addr = 16'h0038;
572
      3'b010:  int_addr = {din1_reg, din0_reg};
573
      3'b1xx:  int_addr = 16'h0066;
574
      default: int_addr = 16'h0000;
575
      endcase
576
    end
577
 
578
  /*****************************************************************************************/
579
  /*                                                                                       */
580
  /* alu input selects                                                                     */
581
  /*                                                                                       */
582
  /*****************************************************************************************/
583
  aluamux AMUX ( .adda_in(adda_in), .alua_in(alua_in), .alua_reg(alua_reg),
584
                 .aa_reg_out(aa_reg_out), .bit_mask(bit_mask), .daa_out(daa_out),
585
                 .hl_reg_out(hl_reg_out), .ii_reg(ii_reg), .int_addr(int_addr),
586
                 .ix_reg(ix_reg), .iy_reg(iy_reg), .pc_reg(pc_reg), .rr_reg(rr_reg),
587
                 .rst_addr(rst_addr) );
588
 
589
  alubmux BMUX ( .addb_in(addb_in), .alub_in(alub_in), .alub_reg(alub_reg),
590
                 .af_reg_out(af_reg_out), .bc_reg_out(bc_reg_out), .de_reg_out(de_reg_out),
591
                 .din0_reg(din0_reg), .din1_reg(din1_reg), .hl_reg_out(hl_reg_out),
592
                 .ix_reg(ix_reg), .iy_reg(iy_reg), .pc_reg(pc_reg), .sp_reg(sp_reg),
593
                 .tmp_reg(tmp_reg) );
594
 
595
  /*****************************************************************************************/
596
  /*                                                                                       */
597
  /* function units                                                                        */
598
  /*                                                                                       */
599
  /*****************************************************************************************/
600
  alu_log  ALULOG  ( .logic_c(logic_c), .logic_hc(logic_hc), .logic_out(logic_out),
601
                     .alua_in(alua_in), .alub_in(alub_in), .aluop_reg(aluop_reg[`AOP_IDX:0]),
602
                     .carry_bit(carry_bit) );
603
 
604
  alu_math ALUMATH ( .adder_c(adder_c), .adder_hc(adder_hc), .adder_out(adder_out),
605
                     .adder_ov(adder_ov), .alua_in(alua_in), .alub_in(alub_in),
606
                     .aluop_reg(aluop_reg[`AOP_IDX:0]), .carry_bit(carry_bit),
607
                     .carry_daa(carry_daa), .daa_op(daa_op), .word_op(word_op) );
608
 
609
  alu_shft ALUSHFT ( .shft_c(shft_c), .shft_out(shft_out), .alub_in(alub_in[7:0]),
610
                     .aluop_reg(aluop_reg[`AOP_IDX:0]), .carry_bit(carry_bit) );
611
 
612
  aluout   ALUOUT  ( .cry_nxt(cry_nxt), .data_bus(data_bus), .hcar_nxt(hcar_nxt),
613
                     .one_nxt(one_nxt), .par_nxt(par_nxt), .sign_nxt(sign_nxt),
614
                     .zero_nxt(zero_nxt), .adder_c(adder_c), .adder_hc(adder_hc),
615
                     .adder_out(adder_out), .hi_byte(hi_byte), .logic_c(logic_c),
616
                     .logic_hc(logic_hc), .logic_out(logic_out), .shft_c(shft_c),
617
                     .shft_out(shft_out), .unit_sel(aluop_reg[7:6]), .word_op(word_op) );
618
 
619
  /*****************************************************************************************/
620
  /*                                                                                       */
621
  /* flag generation                                                                       */
622
  /*                                                                                       */
623
  /*****************************************************************************************/
624
  assign alu_carry = decr_op ^ cry_nxt;
625
  assign alu_hcar  = (hflg_ctl[1]) ? hflg_ctl[0] : (decr_op ^ hcar_nxt);
626
  assign alu_neg   = (nflg_ctl[1]) ? nflg_ctl[0] : sign_nxt;
627
  assign alu_one   = one_nxt;
628
  assign alu_sign  = sign_nxt;
629
  assign alu_zero  = zero_nxt;
630
 
631
  always @ (pflg_ctl or adder_ov or ief2_reg or par_nxt or zero_nxt) begin
632
    case (pflg_ctl)
633
      `PFLG_V: alu_ovflo = adder_ov;
634
      `PFLG_1: alu_ovflo = 1'b1;
635
      `PFLG_P: alu_ovflo = par_nxt;
636
      `PFLG_B: alu_ovflo = !zero_nxt;
637
      `PFLG_F: alu_ovflo = ief2_reg;
638
      default: alu_ovflo = 1'b0;
639
      endcase
640
    end
641
 
642
  assign new_flags[7] = (sflg_en)   ? alu_sign  : ff_reg_out[7];
643
  assign new_flags[6] = (zflg_en)   ? alu_zero  : ff_reg_out[6];
644
  assign new_flags[5] =                           ff_reg_out[5];
645
  assign new_flags[4] = (|hflg_ctl) ? alu_hcar  : ff_reg_out[4];
646
  assign new_flags[3] =                           ff_reg_out[3];
647
  assign new_flags[2] = (|pflg_ctl) ? alu_ovflo : ff_reg_out[2];
648
  assign new_flags[1] = (|nflg_ctl) ? alu_neg   : ff_reg_out[1];
649
  assign new_flags[0] = (cflg_en)   ? alu_carry : ff_reg_out[0];
650
 
651
  /*****************************************************************************************/
652
  /*                                                                                       */
653
  /* address alu                                                                           */
654
  /*                                                                                       */
655
  /*****************************************************************************************/
656
  assign bsign_ext = {addb_in[7],  addb_in[7],  addb_in[7],  addb_in[7],
657
                      addb_in[7],  addb_in[7],  addb_in[7],  addb_in[7]};
658
 
659
  always @ (aluop_reg or adda_in or addb_in or bsign_ext) begin
660
    case (aluop_reg)
661
      `ALUOP_ADS:  adda_out = adda_in + {bsign_ext[15:8], addb_in[7:0]};
662
      `ALUOP_ADD:  adda_out = adda_in + addb_in;
663
      `ALUOP_APAS: adda_out = adda_in;
664
      default:     adda_out = addb_in;
665
      endcase
666
    end
667
 
668
  assign addr_alu = (addsel_reg[`AD_ALU]) ? adda_out   : 16'h0000;
669
  assign addr_hl  = (addsel_reg[`AD_HL])  ? hl_reg_out : 16'h0000;
670
  assign addr_pc  = (addsel_reg[`AD_PC])  ? pc_reg     : 16'h0000;
671
  assign addr_sp  = (addsel_reg[`AD_SP])  ? sp_reg     : 16'h0000;
672
 
673
  assign addr_reg_in = addr_alu | addr_hl | addr_pc | addr_sp;
674
 
675
  endmodule
676
 
677
 
678
 
679
 
680
 
681
 
682
 
683
 
684
 
685
 
686
 

powered by: WebSVN 2.1.0

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