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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
`timescale 1ns / 1ps
module core_selector
(
sys_clk, sys_rst,
sys_eim_addr, sys_eim_wr, sys_eim_rd,
sys_eim_dout, sys_eim_din
);
//
// Ports
//
input wire sys_clk;
input wire sys_rst;
input wire [13: 0] sys_eim_addr;
input wire sys_eim_wr;
input wire sys_eim_rd;
input wire [31: 0] sys_eim_dout;
output wire [31: 0] sys_eim_din;
//
// Internal Registers
//
reg [31: 0] reg_x = {32{1'b0}};
reg [31: 0] reg_y = {32{1'b0}};
reg [15: 0] reg_ctl = {16{1'b0}};
reg [31: 0] sys_eim_din_reg = {32{1'b0}};
//
// Parameters
//
localparam ADDER_BASE_ADDR = 12'h321; // upper 12 bits of address
localparam ADDER_OFFSET_REG_X = 2'd0; // X
localparam ADDER_OFFSET_REG_Y = 2'd1; // Y
localparam ADDER_OFFSET_REG_Z = 2'd2; // Z
localparam ADDER_OFFSET_REG_SC = 2'd3; // {STATUS, CONTROL}
/* This flag detects whether adder core is being addressed. */
wire eim_access_adder = (sys_eim_addr[13:2] == ADDER_BASE_ADDR) ? 1'b1 : 1'b0;
/* These flags detect whether write or read access is requested. */
wire eim_access_write = sys_eim_wr & eim_access_adder;
wire eim_access_read = sys_eim_rd & eim_access_adder;
//
// Write Request Handler
//
always @(posedge sys_clk)
//
if (sys_rst) begin
reg_x <= {32{1'b0}};
reg_y <= {32{1'b0}};
reg_ctl <= {16{1'b0}};
end else if (eim_access_write) begin
//
case (sys_eim_addr[1:0])
ADDER_OFFSET_REG_X: reg_x <= sys_eim_dout;
ADDER_OFFSET_REG_Y: reg_y <= sys_eim_dout;
ADDER_OFFSET_REG_SC: reg_ctl <= sys_eim_dout[15: 0];
endcase
//
end
//
// Read Request Handler
//
wire [31: 0] reg_z;
wire [15: 0] reg_sts;
always @(posedge sys_clk)
//
if (sys_rst) sys_eim_din_reg <= {32{1'b0}};
//
else if (eim_access_read) begin
//
case (sys_eim_addr[1:0])
ADDER_OFFSET_REG_X: sys_eim_din_reg <= reg_x;
ADDER_OFFSET_REG_Y: sys_eim_din_reg <= reg_y;
ADDER_OFFSET_REG_Z: sys_eim_din_reg <= reg_z;
ADDER_OFFSET_REG_SC: sys_eim_din_reg <= {reg_sts, reg_ctl};
endcase
//
end
assign sys_eim_din = sys_eim_din_reg;
//
// Demo Adder Core
//
demo_adder adder_core
(
.clk (sys_clk),
.rst (sys_rst),
.x (reg_x),
.y (reg_y),
.z (reg_z),
.ctl (reg_ctl),
.sts (reg_sts)
);
endmodule
|