aboutsummaryrefslogtreecommitdiff
path: root/rtl/src/verilog/core_selector.v
blob: 2db2a05a5158ac3420a2e510ab5e763418a83709 (plain) (blame)
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