-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathab.v
94 lines (80 loc) · 1.95 KB
/
ab.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
* Address Bus (and PC) generator
*
* Copyright (C) Arlet Ottens, 2022, <[email protected]>
*/
module ab(
input clk,
input RST,
input [9:0] ab_op,
input [7:0] S,
input [7:0] DI,
input [7:0] DR,
input [7:0] XY,
output [15:0] AB,
output reg [15:0] PC );
reg [7:0] ABH;
reg [7:0] ABL;
assign AB = { ABH, ABL };
/*
* ab_hold stores a copy of current address to be used
* later.
*/
reg [15:0] ab_hold;
always @(posedge clk)
if( ab_op[7] )
ab_hold = AB;
/*
* update program counter
*/
always @(posedge clk)
if( RST )
PC <= 16'hfffc;
else case( ab_op[6:5] )
2'b01: PC <= AB + 16'h1;
2'b10: PC <= 16'hfffa;
2'b11: PC <= 16'hfffe;
endcase
/*
* determine base address
*/
reg [15:0] base;
always @*
case( ab_op[4:3] )
2'b00: base = {8'h00, S};
2'b01: base = PC;
2'b10: base = {DI, DR};
2'b11: base = ab_hold;
endcase
/*
* add offset to the base address. We split the address into
* two separate bytes, because sometimes the address should
* wrap within the page, so we can't always let the carry
* go through.
*/
wire abl_ci = ab_op[0]; // carry input from operation
reg abl_co; // carry output from low byte
always @* begin
case( ab_op[2:1] )
2'b00: {abl_co, ABL} = base[7:0] + 00 + abl_ci;
2'b01: {abl_co, ABL} = base[7:0] + XY + abl_ci;
2'b10: {abl_co, ABL} = base[7:0] + DI + abl_ci;
2'b11: {abl_co, ABL} = XY + DI + abl_ci;
endcase
end
/*
* carry input for high byte
*/
wire abh_ci = ab_op[9] & abl_co;
/*
* calculate address high byte
*/
always @* begin
case( ab_op[9:8] )
2'b00: ABH = base[15:8] + 8'h00 + abh_ci; // ci = 0
2'b01: ABH = base[15:8] + 8'h01 + abh_ci; // ci = 0
2'b10: ABH = base[15:8] + 8'h00 + abh_ci; // ci = abl_ci
2'b11: ABH = base[15:8] + 8'hff + abh_ci; // ci = abl_ci
endcase
end
endmodule