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

Subversion Repositories y80e

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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