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

Subversion Repositories y80e

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

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

powered by: WebSVN 2.1.0

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