422 lines
10 KiB
Verilog
422 lines
10 KiB
Verilog
module TopLevel (CLKIN, BTN, SWITCH, LED, SEG, ANODE, RX_A, TX_A,
|
|
SRAM_IO1, SRAM_CE1, SRAM_UB1, SRAM_LB1, SRAM_ADR, SRAM_WE, SRAM_OE,
|
|
SRAM_IO2, SRAM_CE2, SRAM_UB2, SRAM_LB2);
|
|
|
|
input CLKIN;
|
|
|
|
input [3:0] BTN;
|
|
input [7:0] SWITCH;
|
|
output [7:0] LED;
|
|
|
|
output [7:0] SEG;
|
|
output [3:0] ANODE;
|
|
|
|
input RX_A;
|
|
output TX_A;
|
|
|
|
output [17:0] SRAM_ADR;
|
|
output SRAM_WE;
|
|
output SRAM_OE;
|
|
inout [15:0] SRAM_IO1;
|
|
output SRAM_CE1;
|
|
output SRAM_UB1;
|
|
output SRAM_LB1;
|
|
inout [15:0] SRAM_IO2;
|
|
output SRAM_CE2;
|
|
output SRAM_UB2;
|
|
output SRAM_LB2;
|
|
|
|
DCM #(
|
|
.CLKFX_DIVIDE(2), // Can be any integer from 1 to 32
|
|
.CLKFX_MULTIPLY(2), // Can be any integer from 2 to 32
|
|
.CLKIN_PERIOD(20.0), // Period of input clock
|
|
.STARTUP_WAIT("TRUE"), // Delay configuration DONE until DCM LOCK?
|
|
.CLKDV_DIVIDE(2.0), // [1.5,7.5]/0.5 or [8.0,16.0]/1.0
|
|
.CLKIN_DIVIDE_BY_2("FALSE"), // Enable CLKIN divide-by-two feature?
|
|
.CLKOUT_PHASE_SHIFT("NONE"), // NONE, FIXED or VARIABLE
|
|
.CLK_FEEDBACK("1X"), // Specify clock feedback of NONE, 1X or 2X
|
|
.PHASE_SHIFT(0) // Amount of fixed phase shift, -255 to 255
|
|
) DCM0 (
|
|
.CLK0(CLK0_DCM), // CLKOUT w/ 0 degree shift
|
|
// .CLK2X(CLK_100), // 2 * CLK0 frequency
|
|
// .CLKFX(CLKFX), // DCM CLK synthesis out (M/D)
|
|
.CLKIN(CLKIN), // Clock input (from IBUFG, BUFG or DCM)
|
|
.CLKFB(CLK0) // DCM clock feedback
|
|
);
|
|
|
|
BUFG BUFB0 (
|
|
.I(CLK0_DCM),
|
|
.O(CLK0)
|
|
);
|
|
|
|
wire CLK_O = CLK0;
|
|
reg RST_O = 1'b1;
|
|
|
|
wire [31:0] IADR_I;
|
|
wire [31:0] INST_ADR_O;
|
|
wire [7:0] INST_DAT_I;
|
|
wire [31:2] CPU_ADR_O;
|
|
wire [31:0] CPU_DAT_I;
|
|
wire [31:0] CPU_DAT_O;
|
|
wire [3:0] CPU_SEL_O;
|
|
wire CPU_ACK_I;
|
|
|
|
StackCPU MyStackCPU (
|
|
.CLK_I(CLK_O),
|
|
.RST_I(RST_O),
|
|
.IRQ_I(IRQ_I),
|
|
.IADR_I(IADR_I),
|
|
.IACK_O(IACK_O),
|
|
.INST_ADR_O(INST_ADR_O),
|
|
.INST_DAT_I(INST_DAT_I),
|
|
.INST_CYC_O(INST_CYC_O),
|
|
.INST_STB_O(INST_STB_O),
|
|
.INST_ACK_I(INST_ACK_I),
|
|
.DATA_ADR_O(CPU_ADR_O),
|
|
.DATA_DAT_I(CPU_DAT_I),
|
|
.DATA_DAT_O(CPU_DAT_O),
|
|
.DATA_CYC_O(CPU_CYC_O),
|
|
.DATA_STB_O(CPU_STB_O),
|
|
.DATA_WE_O(CPU_WE_O),
|
|
.DATA_SEL_O(CPU_SEL_O),
|
|
.DATA_ACK_I(CPU_ACK_I)
|
|
);
|
|
|
|
// Bus arbiter master signals
|
|
wire [31:2] DATA_ADR_O;
|
|
reg [31:0] DATA_DAT_I;
|
|
wire [31:0] DATA_DAT_O;
|
|
wire [3:0] DATA_SEL_O;
|
|
reg DATA_ACK_I;
|
|
|
|
`define SLV_PROGRAM_RAM 4'b0000
|
|
`define SLV_SRAM 4'b0001
|
|
`define SLV_IRQ_CTL 4'b0010
|
|
`define SLV_DMA_CTL 4'b0011
|
|
`define SLV_TIMER 4'b0100
|
|
`define SLV_LED_SWITCH 4'b0101
|
|
`define SLV_BTN_DISPLAY 4'b0110
|
|
`define SLV_RS232 4'b0111
|
|
`define SLV_UNUSED 4'b1111
|
|
reg [3:0] SLAVE;
|
|
|
|
always @*
|
|
begin
|
|
/*
|
|
casex (DATA_ADR_O)
|
|
30'bXXXX_XXXX_XX00_XXXX_XXXX_XXXX_XXXX_XX: SLAVE <= `SLV_PROGRAM_RAM;
|
|
30'bXXXX_XXXX_XX01_XXXX_XXXX_XXXX_XXXX_XX: SLAVE <= `SLV_SRAM;
|
|
30'bXXXX_XXXX_XX11_XXXX_XXXX_XXXX_X0XX_XX: SLAVE <= `SLV_IRQ_CTL;
|
|
30'bXXXX_XXXX_XX11_XXXX_XXXX_XXXX_X10X_XX: SLAVE <= `SLV_DMA_CTL;
|
|
30'bXXXX_XXXX_XX11_XXXX_XXXX_XXXX_X110_XX: SLAVE <= `SLV_TIMER;
|
|
30'bXXXX_XXXX_XX11_XXXX_XXXX_XXXX_X111_00: SLAVE <= `SLV_LED_SWITCH;
|
|
30'bXXXX_XXXX_XX11_XXXX_XXXX_XXXX_X111_01: SLAVE <= `SLV_BTN_DISPLAY;
|
|
30'bXXXX_XXXX_XX11_XXXX_XXXX_XXXX_X111_1X: SLAVE <= `SLV_RS232;
|
|
default: SLAVE <= `SLV_UNUSED;
|
|
endcase
|
|
*/
|
|
// Manually decode the above table, because xst appears to
|
|
// attempt to expand it rather than ignore the 'X' bits.
|
|
case (DATA_ADR_O[21:20])
|
|
2'b00: SLAVE <= `SLV_PROGRAM_RAM;
|
|
2'b01: SLAVE <= `SLV_SRAM;
|
|
2'b10: SLAVE <= `SLV_UNUSED;
|
|
2'b11:
|
|
casex (DATA_ADR_O[6:2])
|
|
5'b0XX_XX: SLAVE <= `SLV_IRQ_CTL;
|
|
5'b10X_XX: SLAVE <= `SLV_DMA_CTL;
|
|
5'b110_XX: SLAVE <= `SLV_TIMER;
|
|
5'b111_00: SLAVE <= `SLV_LED_SWITCH;
|
|
5'b111_01: SLAVE <= `SLV_BTN_DISPLAY;
|
|
5'b111_1X: SLAVE <= `SLV_RS232;
|
|
default: SLAVE <= `SLV_UNUSED;
|
|
endcase
|
|
endcase
|
|
end
|
|
|
|
wire [31:0] DMA_CTL_DAT_O;
|
|
wire [31:2] DMA_SRC_ADR_O;
|
|
wire [31:0] DMA_SRC_DAT_I;
|
|
wire [31:2] DMA_DST_ADR_O;
|
|
wire [31:0] DMA_DST_DAT_O;
|
|
|
|
WB_DMA DMAController (
|
|
.CLK_I(CLK_O),
|
|
.RST_I(RST_O),
|
|
.IRQ_O(DMA_IRQ_O),
|
|
.CTL_ADR_I(DATA_ADR_O[3:2]),
|
|
.CTL_DAT_I(DATA_DAT_O),
|
|
.CTL_DAT_O(DMA_CTL_DAT_O),
|
|
.CTL_STB_I(DATA_STB_O & (SLAVE == `SLV_DMA_CTL)),
|
|
.CTL_WE_I(DATA_WE_O),
|
|
.CTL_ACK_O(DMA_CTL_ACK_O),
|
|
.SRC_ADR_O(DMA_SRC_ADR_O),
|
|
.SRC_DAT_I(DMA_SRC_DAT_I),
|
|
.SRC_STB_O(DMA_SRC_STB_O),
|
|
.SRC_WE_O(DMA_SRC_WE_O),
|
|
.SRC_ACK_I(DMA_SRC_ACK_I),
|
|
.DST_ADR_O(DMA_DST_ADR_O),
|
|
.DST_DAT_O(DMA_DST_DAT_O),
|
|
.DST_STB_O(DMA_DST_STB_O),
|
|
.DST_WE_O(DMA_DST_WE_O),
|
|
.DST_ACK_I(DMA_DST_ACK_I)
|
|
);
|
|
|
|
wire [31:2] DMA_ADR_O;
|
|
wire [31:0] DMA_DAT_O;
|
|
wire [31:0] DMA_DAT_I;
|
|
wire [3:0] DMA_SEL_O;
|
|
wire DMA_ACK_I;
|
|
|
|
WB_ARB_2M DMAArbiter (
|
|
.CLK_I(CLK_O),
|
|
.RST_I(RST_O),
|
|
|
|
.M0_ADR_I(DMA_SRC_ADR_O),
|
|
.M0_DAT_I(32'd0),
|
|
.M0_DAT_O(DMA_SRC_DAT_I),
|
|
.M0_LOCK_I(1'b0),
|
|
.M0_CYC_I(DMA_SRC_STB_O),
|
|
.M0_STB_I(DMA_SRC_STB_O),
|
|
.M0_WE_I(DMA_SRC_WE_O),
|
|
.M0_SEL_I(4'b1111),
|
|
.M0_ACK_O(DMA_SRC_ACK_I),
|
|
|
|
.M1_ADR_I(DMA_DST_ADR_O),
|
|
.M1_DAT_I(DMA_DST_DAT_O),
|
|
.M1_LOCK_I(1'b0),
|
|
.M1_CYC_I(DMA_DST_STB_O),
|
|
.M1_STB_I(DMA_DST_STB_O),
|
|
.M1_WE_I(DMA_DST_WE_O),
|
|
.M1_SEL_I(4'b1111),
|
|
.M1_ACK_O(DMA_DST_ACK_I),
|
|
|
|
.S_ADR_O(DMA_ADR_O),
|
|
.S_DAT_O(DMA_DAT_O),
|
|
.S_DAT_I(DMA_DAT_I),
|
|
.S_CYC_O(DMA_CYC_O),
|
|
.S_STB_O(DMA_STB_O),
|
|
.S_WE_O(DMA_WE_O),
|
|
.S_SEL_O(DMA_SEL_O),
|
|
.S_ACK_I(DMA_ACK_I),
|
|
.S_ERR_I(1'b0),
|
|
.S_RTY_I(1'b0)
|
|
);
|
|
|
|
WB_ARB_2M BusArbiter (
|
|
.CLK_I(CLK_O),
|
|
.RST_I(RST_O),
|
|
|
|
.M0_ADR_I(CPU_ADR_O),
|
|
.M0_DAT_I(CPU_DAT_O),
|
|
.M0_DAT_O(CPU_DAT_I),
|
|
.M0_LOCK_I(1'b0),
|
|
.M0_CYC_I(CPU_CYC_O),
|
|
.M0_STB_I(CPU_STB_O),
|
|
.M0_WE_I(CPU_WE_O),
|
|
.M0_SEL_I(CPU_SEL_O),
|
|
.M0_ACK_O(CPU_ACK_I),
|
|
|
|
.M1_ADR_I(DMA_ADR_O),
|
|
.M1_DAT_I(DMA_DAT_O),
|
|
.M1_DAT_O(DMA_DAT_I),
|
|
.M1_LOCK_I(1'b0),
|
|
.M1_CYC_I(DMA_CYC_O),
|
|
.M1_STB_I(DMA_STB_O),
|
|
.M1_WE_I(DMA_WE_O),
|
|
.M1_SEL_I(DMA_SEL_O),
|
|
.M1_ACK_O(DMA_ACK_I),
|
|
|
|
.S_ADR_O(DATA_ADR_O),
|
|
.S_DAT_O(DATA_DAT_O),
|
|
.S_DAT_I(DATA_DAT_I),
|
|
.S_STB_O(DATA_STB_O),
|
|
.S_WE_O(DATA_WE_O),
|
|
.S_SEL_O(DATA_SEL_O),
|
|
.S_ACK_I(DATA_ACK_I),
|
|
.S_ERR_I(1'b0),
|
|
.S_RTY_I(1'b0)
|
|
);
|
|
|
|
wire [31:0] TIMER_DAT_O;
|
|
|
|
TIMER #(
|
|
.INIT_RELOAD(32'd49999)
|
|
) Timer (
|
|
.CLK_I(CLK_O),
|
|
.RST_I(RST_O),
|
|
.ADR_I(DATA_ADR_O[3:2]),
|
|
.DAT_I(DATA_DAT_O),
|
|
.DAT_O(TIMER_DAT_O),
|
|
.STB_I(DATA_STB_O & (SLAVE == `SLV_TIMER)),
|
|
.WE_I(DATA_WE_O),
|
|
.ACK_O(TIMER_ACK_O),
|
|
.IRQ_O(TIMER_IRQ_O)
|
|
);
|
|
|
|
wire RS232_TX_FULL;
|
|
wire RS232_RX_EMPTY;
|
|
wire [31:0] IRQ_DAT_O;
|
|
|
|
IRQ_CTL InterruptController (
|
|
.CLK_I(CLK_O),
|
|
.RST_I(RST_O),
|
|
.IRQ_O(IRQ_I),
|
|
.IADR_O(IADR_I),
|
|
.IACK_I(IACK_O),
|
|
.ADR_I(DATA_ADR_O[5:2]),
|
|
.DAT_I(DATA_DAT_O),
|
|
.DAT_O(IRQ_DAT_O),
|
|
.STB_I(DATA_STB_O & (SLAVE == `SLV_IRQ_CTL)),
|
|
.WE_I(DATA_WE_O),
|
|
.SEL_I(DATA_SEL_O),
|
|
.ACK_O(IRQ_ACK_O),
|
|
.IRQ0(1'b0),
|
|
.IRQ1(~RS232_RX_EMPTY),
|
|
.IRQ2(DMA_IRQ_O),
|
|
.IRQ3(~RS232_TX_FULL),
|
|
.IRQ4(TIMER_IRQ_O),
|
|
.IRQ5(1'b0),
|
|
.IRQ6(1'b0),
|
|
.IRQ7(1'b0)
|
|
);
|
|
|
|
wire [31:0] PROGRAM_DAT_O;
|
|
|
|
ProgramRAM Program (
|
|
.CLK_I(CLK_O),
|
|
.RST_I(RST_O),
|
|
.INST_ADR_I(INST_ADR_O[12:0]),
|
|
.INST_DAT_O(INST_DAT_I),
|
|
.INST_STB_I(INST_STB_O),
|
|
.INST_ACK_O(INST_ACK_I),
|
|
.DATA_ADR_I(DATA_ADR_O[12:2]),
|
|
.DATA_DAT_I(DATA_DAT_O),
|
|
.DATA_DAT_O(PROGRAM_DAT_O),
|
|
.DATA_STB_I(DATA_STB_O & (SLAVE == `SLV_PROGRAM_RAM)),
|
|
.DATA_WE_I(DATA_WE_O),
|
|
.DATA_SEL_I(DATA_SEL_O),
|
|
.DATA_ACK_O(PROGRAM_ACK_O)
|
|
);
|
|
|
|
wire [31:0] SRAM_DAT_O;
|
|
|
|
WB_SRAM WishboneSRAM (
|
|
.CLK_I(CLK_O),
|
|
.RST_I(RST_O),
|
|
.ADR_I(DATA_ADR_O[19:2]),
|
|
.DAT_I(DATA_DAT_O),
|
|
.DAT_O(SRAM_DAT_O),
|
|
.STB_I(DATA_STB_O & (SLAVE == `SLV_SRAM)),
|
|
.WE_I(DATA_WE_O),
|
|
.SEL_I(DATA_SEL_O),
|
|
.ACK_O(SRAM_ACK_O),
|
|
.SRAM_ADR(SRAM_ADR),
|
|
.SRAM_WE(SRAM_WE),
|
|
.SRAM_OE(SRAM_OE),
|
|
.SRAM_IO1(SRAM_IO1),
|
|
.SRAM_CE1(SRAM_CE1),
|
|
.SRAM_UB1(SRAM_UB1),
|
|
.SRAM_LB1(SRAM_LB1),
|
|
.SRAM_IO2(SRAM_IO2),
|
|
.SRAM_CE2(SRAM_CE2),
|
|
.SRAM_UB2(SRAM_UB2),
|
|
.SRAM_LB2(SRAM_LB2)
|
|
);
|
|
|
|
wire [31:0] RS232_DAT_O;
|
|
|
|
RS232 #(
|
|
.CLOCK_DIV(434) // 115200 bps @ 50 MHz CLKIN
|
|
) SerialInterface (
|
|
.CLK_I(CLK_O),
|
|
.RST_I(RST_O),
|
|
.DAT_I(DATA_DAT_O),
|
|
.DAT_O(RS232_DAT_O),
|
|
.STB_I(DATA_STB_O & (SLAVE == `SLV_RS232)),
|
|
.WE_I(DATA_WE_O),
|
|
.SEL_I(DATA_SEL_O),
|
|
.ACK_O(RS232_ACK_O),
|
|
.TX_FULL(RS232_TX_FULL),
|
|
.RX_EMPTY(RS232_RX_EMPTY),
|
|
.RX(RX_A),
|
|
.TX(TX_A)
|
|
);
|
|
|
|
reg [7:0] SWITCH_R;
|
|
reg [3:0] BTN_R;
|
|
reg [7:0] LED = 8'h00;
|
|
reg [19:0] DISPLAY = 20'h00000;
|
|
|
|
SevenSeg Display (
|
|
.CLKIN(CLK_O),
|
|
.INPUT(DISPLAY[15:0]),
|
|
//.INPUT(INST_ADR_O[15:0]),
|
|
//.INPUT(DATA_ADR_O[17:2]),
|
|
.DP(DISPLAY[19:16]),
|
|
.SEG(SEG),
|
|
.ANODE(ANODE)
|
|
);
|
|
|
|
always @*
|
|
begin
|
|
case (SLAVE)
|
|
`SLV_PROGRAM_RAM: DATA_DAT_I <= PROGRAM_DAT_O;
|
|
`SLV_SRAM: DATA_DAT_I <= SRAM_DAT_O;
|
|
`SLV_IRQ_CTL: DATA_DAT_I <= IRQ_DAT_O;
|
|
`SLV_DMA_CTL: DATA_DAT_I <= DMA_CTL_DAT_O;
|
|
`SLV_TIMER: DATA_DAT_I <= TIMER_DAT_O;
|
|
`SLV_LED_SWITCH: DATA_DAT_I <= { 24'h0, SWITCH_R };
|
|
`SLV_BTN_DISPLAY: DATA_DAT_I <= { 4'h0, BTN_R, 4'h0, DISPLAY };
|
|
`SLV_RS232: DATA_DAT_I <= RS232_DAT_O;
|
|
default: DATA_DAT_I <= 32'hA5A5A5A5;
|
|
endcase
|
|
|
|
case (SLAVE)
|
|
`SLV_PROGRAM_RAM: DATA_ACK_I <= PROGRAM_ACK_O;
|
|
`SLV_SRAM: DATA_ACK_I <= SRAM_ACK_O;
|
|
`SLV_IRQ_CTL: DATA_ACK_I <= IRQ_ACK_O;
|
|
`SLV_DMA_CTL: DATA_ACK_I <= DMA_CTL_ACK_O;
|
|
`SLV_TIMER: DATA_ACK_I <= TIMER_ACK_O;
|
|
`SLV_RS232: DATA_ACK_I <= RS232_ACK_O;
|
|
default: DATA_ACK_I <= DATA_STB_O;
|
|
endcase
|
|
end
|
|
|
|
reg [15:0] RST_CNT = 16'hFFFF;
|
|
|
|
always @(posedge CLK_O)
|
|
begin
|
|
if (BTN_R[3] & ~&RST_CNT)
|
|
RST_CNT <= RST_CNT + 16'd1;
|
|
else if (|RST_CNT)
|
|
RST_CNT <= RST_CNT - 16'd1;
|
|
|
|
if (RST_CNT == 16'hFFFF)
|
|
RST_O <= 1'b1;
|
|
else if (RST_CNT == 16'h0000)
|
|
RST_O <= 1'b0;
|
|
end
|
|
|
|
always @(posedge CLK_O)
|
|
begin
|
|
BTN_R <= BTN;
|
|
SWITCH_R <= SWITCH;
|
|
|
|
if (DATA_STB_O & DATA_WE_O)
|
|
begin
|
|
case (SLAVE)
|
|
`SLV_LED_SWITCH:
|
|
LED <= DATA_DAT_O[7:0];
|
|
`SLV_BTN_DISPLAY:
|
|
begin
|
|
if (DATA_SEL_O[2]) DISPLAY[19:16] <= DATA_DAT_O[19:16];
|
|
if (DATA_SEL_O[1]) DISPLAY[15: 8] <= DATA_DAT_O[15: 8];
|
|
if (DATA_SEL_O[0]) DISPLAY[ 7: 0] <= DATA_DAT_O[ 7: 0];
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
endmodule
|