Added timer, still wip
This commit is contained in:
126
rtl/core/mcu.v
126
rtl/core/mcu.v
@@ -16,7 +16,8 @@ module mcu #(
|
||||
output wire [31:0] o_GPO_A,
|
||||
output wire [31:0] o_GPO_B,
|
||||
output wire [31:0] o_GPO_C,
|
||||
output wire [31:0] o_GPO_D
|
||||
output wire [31:0] o_GPO_D,
|
||||
output wire o_test
|
||||
);
|
||||
localparam WITH_CSR = 1;
|
||||
localparam regs = 32+WITH_CSR*4;
|
||||
@@ -26,7 +27,8 @@ module mcu #(
|
||||
wire rst_mem_reason;
|
||||
wire timer_irq;
|
||||
assign rst = i_rst | rst_mem_reason;
|
||||
assign timer_irq = 1'b0;
|
||||
|
||||
assign o_test = timer_irq;
|
||||
|
||||
// Busses
|
||||
// CPU->memory
|
||||
@@ -72,9 +74,6 @@ module mcu #(
|
||||
assign GPI[32*3-1:32*2] = i_GPI_C;
|
||||
assign GPI[32*4-1:32*3] = i_GPI_D;
|
||||
|
||||
assign wb_ext_ack = wb_ext_gpio_ack;
|
||||
assign wb_ext_rdt = wb_ext_gpio_rdt;
|
||||
|
||||
// SERV core with mux splitting dbus into mem and ext and
|
||||
// arbiter combining mem and ibus
|
||||
// separate rst line to let other hardware keep core under reset
|
||||
@@ -89,7 +88,7 @@ module mcu #(
|
||||
) servile (
|
||||
.i_clk(i_clk),
|
||||
.i_rst(rst),
|
||||
.i_timer_irq(timer_irq),
|
||||
.i_timer_irq(1'b0), //timer_irq),
|
||||
|
||||
//Memory interface
|
||||
.o_wb_mem_adr(wb_mem_adr),
|
||||
@@ -119,14 +118,14 @@ module mcu #(
|
||||
);
|
||||
|
||||
// WB arbiter combining RF and mem interfaces into 1
|
||||
// Last 128 bytes are used for registers
|
||||
// Last 128 bytes are used for registers
|
||||
servile_rf_mem_if #(
|
||||
.depth(memsize),
|
||||
.rf_regs(regs)
|
||||
) rf_mem_if (
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
|
||||
.i_rst (rst),
|
||||
|
||||
.i_waddr(rf_waddr),
|
||||
.i_wdata(rf_wdata),
|
||||
.i_wen(rf_wen),
|
||||
@@ -165,111 +164,20 @@ module mcu #(
|
||||
.o_core_reset(rst_mem_reason)
|
||||
);
|
||||
|
||||
wb_gpio_banks #(
|
||||
.BASE_ADDR(32'h40000000),
|
||||
.NUM_BANKS(4)
|
||||
) gpio (
|
||||
.i_wb_clk(i_clk),
|
||||
.i_wb_rst(rst),
|
||||
.i_wb_dat(wb_ext_dat),
|
||||
mcu_peripherals peripherals (
|
||||
.i_clk(i_clk),
|
||||
.i_rst(rst),
|
||||
.i_wb_adr(wb_ext_adr),
|
||||
.i_wb_dat(wb_ext_dat),
|
||||
.i_wb_sel(wb_ext_sel),
|
||||
.i_wb_we(wb_ext_we),
|
||||
.i_wb_stb(wb_ext_stb),
|
||||
.i_wb_sel(wb_ext_sel),
|
||||
.o_wb_rdt(wb_ext_rdt),
|
||||
.o_wb_ack(wb_ext_ack),
|
||||
// Peripheral IO
|
||||
.i_gpio(GPI),
|
||||
.o_gpio(GPO)
|
||||
.o_gpio(GPO),
|
||||
.o_timer_irq(timer_irq)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
module memory #(
|
||||
parameter memfile = "",
|
||||
parameter depth = 256,
|
||||
parameter sim = 1'b0,
|
||||
localparam aw = `CLOG2(depth)
|
||||
)(
|
||||
input wire i_clk,
|
||||
input wire i_rst,
|
||||
input wire [aw-1:0] i_waddr,
|
||||
input wire [7:0] i_wdata,
|
||||
input wire i_wen,
|
||||
input wire [aw-1:0] i_raddr,
|
||||
output reg [7:0] o_rdata,
|
||||
output wire o_core_reset
|
||||
);
|
||||
// The actual memory
|
||||
reg [7:0] mem [0:depth-1];
|
||||
wire [aw-1:0] mem_adr;
|
||||
assign mem_adr = (i_wen==1'b1) ? i_waddr :
|
||||
i_raddr;
|
||||
|
||||
// Second port wishbone
|
||||
wire [31:0] wb_adr;
|
||||
wire [31:0] wb_dat;
|
||||
reg [31:0] wb_rdt;
|
||||
wire [3:0] wb_sel;
|
||||
wire wb_cyc;
|
||||
wire wb_we;
|
||||
wire wb_stb;
|
||||
reg wb_ack;
|
||||
reg wb_req_d;
|
||||
wire cmd_reset;
|
||||
// Driven by JTAG
|
||||
jtag_wb_bridge #(
|
||||
.chain(1),
|
||||
.byte_aligned(1)
|
||||
) jtag_wb (
|
||||
.i_clk(i_clk),
|
||||
.i_rst(i_rst),
|
||||
|
||||
.o_wb_adr(wb_adr),
|
||||
.o_wb_dat(wb_dat),
|
||||
.o_wb_sel(wb_sel),
|
||||
.o_wb_we(wb_we),
|
||||
.o_wb_cyc(wb_cyc),
|
||||
.o_wb_stb(wb_stb),
|
||||
.i_wb_rdt(wb_rdt),
|
||||
.i_wb_ack(wb_ack),
|
||||
.o_cmd_reset(cmd_reset)
|
||||
);
|
||||
|
||||
assign o_core_reset = cmd_reset;
|
||||
|
||||
// Read/Write
|
||||
always @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
wb_req_d <= 1'b0;
|
||||
wb_ack <= 1'b0;
|
||||
wb_rdt <= 32'h00000000;
|
||||
o_rdata <= 32'h00000000;
|
||||
end else begin
|
||||
if (i_wen)
|
||||
mem[mem_adr] <= i_wdata;
|
||||
o_rdata <= mem[mem_adr];
|
||||
|
||||
wb_req_d <= wb_stb && wb_cyc;
|
||||
wb_ack <= wb_req_d;
|
||||
if (wb_we && wb_stb && wb_cyc)
|
||||
mem[wb_adr[aw-1:0]] <= wb_dat[7:0];
|
||||
wb_rdt <= {24'h000000, mem[wb_adr[aw-1:0]]};
|
||||
end
|
||||
end
|
||||
|
||||
// Preload memory
|
||||
integer i;
|
||||
initial begin
|
||||
if(sim==1'b1) begin
|
||||
for (i = 0; i < depth; i = i + 1)
|
||||
mem[i] = 8'h00;
|
||||
end
|
||||
if(|memfile) begin
|
||||
$display("Preloading %m from %s", memfile);
|
||||
$readmemh(memfile, mem);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
endmodule
|
||||
123
rtl/core/mcu_peripherals.v
Normal file
123
rtl/core/mcu_peripherals.v
Normal file
@@ -0,0 +1,123 @@
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module mcu_peripherals (
|
||||
input wire i_clk,
|
||||
input wire i_rst,
|
||||
|
||||
input wire [31:0] i_wb_adr,
|
||||
input wire [31:0] i_wb_dat,
|
||||
input wire [3:0] i_wb_sel,
|
||||
input wire i_wb_we,
|
||||
input wire i_wb_stb,
|
||||
output wire [31:0] o_wb_rdt,
|
||||
output wire o_wb_ack,
|
||||
|
||||
input wire [4*32-1:0] i_gpio,
|
||||
output wire [4*32-1:0] o_gpio,
|
||||
output wire o_timer_irq
|
||||
);
|
||||
localparam [31:0] GPIO_BASE_ADDR = 32'h4000_0000;
|
||||
localparam [31:0] GPIO_ADDR_MASK = 32'hFFFF_0000;
|
||||
localparam [31:0] TIMER_BASE_ADDR = 32'h4001_0000;
|
||||
localparam [31:0] TIMER_ADDR_MASK = 32'hFFFF_0000;
|
||||
|
||||
wire [2*32-1:0] wbs_adr;
|
||||
wire [2*32-1:0] wbs_dat_w;
|
||||
wire [2*4-1:0] wbs_sel;
|
||||
wire [1:0] wbs_we;
|
||||
wire [1:0] wbs_cyc;
|
||||
wire [1:0] wbs_stb;
|
||||
wire [2*3-1:0] wbs_cti;
|
||||
wire [2*2-1:0] wbs_bte;
|
||||
wire [2*32-1:0] wbs_dat_r;
|
||||
wire [1:0] wbs_ack;
|
||||
|
||||
wire [31:0] gpio_wbs_adr = wbs_adr[0*32 +: 32];
|
||||
wire [31:0] gpio_wbs_dat_w = wbs_dat_w[0*32 +: 32];
|
||||
wire [3:0] gpio_wbs_sel = wbs_sel[0*4 +: 4];
|
||||
wire gpio_wbs_we = wbs_we[0];
|
||||
wire gpio_wbs_cyc = wbs_cyc[0];
|
||||
wire gpio_wbs_stb = wbs_stb[0];
|
||||
wire [31:0] gpio_wbs_dat_r;
|
||||
wire gpio_wbs_ack;
|
||||
|
||||
wire [31:0] timer_wbs_dat_w = wbs_dat_w[1*32 +: 32];
|
||||
wire timer_wbs_we = wbs_we[1];
|
||||
wire timer_wbs_cyc = wbs_cyc[1];
|
||||
wire timer_wbs_stb = wbs_stb[1];
|
||||
wire [31:0] timer_wbs_dat_r;
|
||||
wire timer_wbs_ack;
|
||||
|
||||
wb_mux #(
|
||||
.dw(32),
|
||||
.aw(32),
|
||||
.num_slaves(2),
|
||||
.MATCH_ADDR({TIMER_BASE_ADDR, GPIO_BASE_ADDR}),
|
||||
.MATCH_MASK({TIMER_ADDR_MASK, GPIO_ADDR_MASK})
|
||||
) ext_mux (
|
||||
.wb_clk_i(i_clk),
|
||||
.wb_rst_i(i_rst),
|
||||
|
||||
.wbm_adr_i(i_wb_adr),
|
||||
.wbm_dat_i(i_wb_dat),
|
||||
.wbm_sel_i(i_wb_sel),
|
||||
.wbm_we_i(i_wb_we),
|
||||
.wbm_cyc_i(i_wb_stb),
|
||||
.wbm_stb_i(i_wb_stb),
|
||||
.wbm_cti_i(3'b000),
|
||||
.wbm_bte_i(2'b00),
|
||||
.wbm_dat_o(o_wb_rdt),
|
||||
.wbm_ack_o(o_wb_ack),
|
||||
.wbm_err_o(),
|
||||
.wbm_rty_o(),
|
||||
|
||||
.wbs_adr_o(wbs_adr),
|
||||
.wbs_dat_o(wbs_dat_w),
|
||||
.wbs_sel_o(wbs_sel),
|
||||
.wbs_we_o(wbs_we),
|
||||
.wbs_cyc_o(wbs_cyc),
|
||||
.wbs_stb_o(wbs_stb),
|
||||
.wbs_cti_o(wbs_cti),
|
||||
.wbs_bte_o(wbs_bte),
|
||||
.wbs_dat_i(wbs_dat_r),
|
||||
.wbs_ack_i(wbs_ack),
|
||||
.wbs_err_i(2'b00),
|
||||
.wbs_rty_i(2'b00)
|
||||
);
|
||||
|
||||
wb_gpio_banks #(
|
||||
.BASE_ADDR(GPIO_BASE_ADDR),
|
||||
.NUM_BANKS(4)
|
||||
) gpio (
|
||||
.i_wb_clk(i_clk),
|
||||
.i_wb_rst(i_rst),
|
||||
.i_wb_dat(gpio_wbs_dat_w),
|
||||
.i_wb_adr(gpio_wbs_adr),
|
||||
.i_wb_we(gpio_wbs_we),
|
||||
.i_wb_stb(gpio_wbs_stb & gpio_wbs_cyc),
|
||||
.i_wb_sel(gpio_wbs_sel),
|
||||
.o_wb_rdt(gpio_wbs_dat_r),
|
||||
.o_wb_ack(gpio_wbs_ack),
|
||||
.i_gpio(i_gpio),
|
||||
.o_gpio(o_gpio)
|
||||
);
|
||||
|
||||
assign wbs_dat_r[0*32 +: 32] = gpio_wbs_dat_r;
|
||||
assign wbs_ack[0] = gpio_wbs_ack;
|
||||
|
||||
wb_countdown_timer timer (
|
||||
.i_clk(i_clk),
|
||||
.i_rst(i_rst),
|
||||
.o_irq(o_timer_irq),
|
||||
.i_wb_dat(timer_wbs_dat_w),
|
||||
.o_wb_dat(timer_wbs_dat_r),
|
||||
.i_wb_we(timer_wbs_we),
|
||||
.i_wb_cyc(timer_wbs_cyc),
|
||||
.i_wb_stb(timer_wbs_stb),
|
||||
.o_wb_ack(timer_wbs_ack)
|
||||
);
|
||||
|
||||
|
||||
assign wbs_dat_r[1*32 +: 32] = timer_wbs_dat_r;
|
||||
assign wbs_ack[1] = timer_wbs_ack;
|
||||
endmodule
|
||||
91
rtl/core/mem_jtag_writable.v
Normal file
91
rtl/core/mem_jtag_writable.v
Normal file
@@ -0,0 +1,91 @@
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module memory #(
|
||||
parameter memfile = "",
|
||||
parameter depth = 256,
|
||||
parameter sim = 1'b0,
|
||||
parameter aw = `CLOG2(depth)
|
||||
)(
|
||||
input wire i_clk,
|
||||
input wire i_rst,
|
||||
input wire [aw-1:0] i_waddr,
|
||||
input wire [7:0] i_wdata,
|
||||
input wire i_wen,
|
||||
input wire [aw-1:0] i_raddr,
|
||||
output reg [7:0] o_rdata,
|
||||
output wire o_core_reset
|
||||
);
|
||||
// The actual memory
|
||||
reg [7:0] mem [0:depth-1];
|
||||
wire [aw-1:0] mem_adr;
|
||||
assign mem_adr = (i_wen==1'b1) ? i_waddr :
|
||||
i_raddr;
|
||||
|
||||
// Second port wishbone
|
||||
wire [31:0] wb_adr;
|
||||
wire [31:0] wb_dat;
|
||||
reg [31:0] wb_rdt;
|
||||
wire [3:0] wb_sel;
|
||||
wire wb_cyc;
|
||||
wire wb_we;
|
||||
wire wb_stb;
|
||||
reg wb_ack;
|
||||
reg wb_req_d;
|
||||
wire cmd_reset;
|
||||
// Driven by JTAG
|
||||
jtag_wb_bridge #(
|
||||
.chain(1),
|
||||
.byte_aligned(1)
|
||||
) jtag_wb (
|
||||
.i_clk(i_clk),
|
||||
.i_rst(i_rst),
|
||||
|
||||
.o_wb_adr(wb_adr),
|
||||
.o_wb_dat(wb_dat),
|
||||
.o_wb_sel(wb_sel),
|
||||
.o_wb_we(wb_we),
|
||||
.o_wb_cyc(wb_cyc),
|
||||
.o_wb_stb(wb_stb),
|
||||
.i_wb_rdt(wb_rdt),
|
||||
.i_wb_ack(wb_ack),
|
||||
.o_cmd_reset(cmd_reset)
|
||||
);
|
||||
|
||||
assign o_core_reset = cmd_reset;
|
||||
|
||||
// Read/Write
|
||||
always @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
wb_req_d <= 1'b0;
|
||||
wb_ack <= 1'b0;
|
||||
wb_rdt <= 32'h00000000;
|
||||
o_rdata <= 32'h00000000;
|
||||
end else begin
|
||||
if (i_wen)
|
||||
mem[mem_adr] <= i_wdata;
|
||||
o_rdata <= mem[mem_adr];
|
||||
|
||||
wb_req_d <= wb_stb && wb_cyc;
|
||||
wb_ack <= wb_req_d;
|
||||
if (wb_we && wb_stb && wb_cyc)
|
||||
mem[wb_adr[aw-1:0]] <= wb_dat[7:0];
|
||||
wb_rdt <= {24'h000000, mem[wb_adr[aw-1:0]]};
|
||||
end
|
||||
end
|
||||
|
||||
// Preload memory
|
||||
integer i;
|
||||
initial begin
|
||||
if(sim==1'b1) begin
|
||||
for (i = 0; i < depth; i = i + 1)
|
||||
mem[i] = 8'h00;
|
||||
end
|
||||
if(|memfile) begin
|
||||
$display("Preloading %m from %s", memfile);
|
||||
$readmemh(memfile, mem);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
@@ -1,77 +0,0 @@
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module soclet #(
|
||||
parameter memfile = "",
|
||||
parameter memsize = 8192,
|
||||
parameter sim = 1'b0
|
||||
)(
|
||||
input wire i_clk,
|
||||
input wire i_rst,
|
||||
|
||||
input wire [31:0] i_GPI_A,
|
||||
input wire [31:0] i_GPI_B,
|
||||
input wire [31:0] i_GPI_C,
|
||||
input wire [31:0] i_GPI_D,
|
||||
|
||||
output wire [31:0] o_GPO_A,
|
||||
output wire [31:0] o_GPO_B,
|
||||
output wire [31:0] o_GPO_C,
|
||||
output wire [31:0] o_GPO_D
|
||||
);
|
||||
|
||||
wire [31:0] wb_adr;
|
||||
wire [31:0] wb_dat;
|
||||
wire [31:0] wb_rdt;
|
||||
wire [3:0] wb_sel;
|
||||
wire wb_we;
|
||||
wire wb_stb;
|
||||
wire wb_ack;
|
||||
|
||||
wire [4*32-1:0] GPO;
|
||||
wire [4*32-1:0] GPI;
|
||||
assign o_GPO_A = GPO[32*1-1:32*0];
|
||||
assign o_GPO_B = GPO[32*2-1:32*1];
|
||||
assign o_GPO_C = GPO[32*3-1:32*2];
|
||||
assign o_GPO_D = GPO[32*4-1:32*3];
|
||||
assign GPI[32*1-1:32*0] = i_GPI_A;
|
||||
assign GPI[32*2-1:32*1] = i_GPI_B;
|
||||
assign GPI[32*3-1:32*2] = i_GPI_C;
|
||||
assign GPI[32*4-1:32*3] = i_GPI_D;
|
||||
|
||||
serving #(
|
||||
.memfile(memfile),
|
||||
.memsize(memsize),
|
||||
.sim(sim),
|
||||
.RESET_STRATEGY("MINI"),
|
||||
.WITH_CSR(1)
|
||||
) serv (
|
||||
.i_clk(i_clk),
|
||||
.i_rst(i_rst),
|
||||
.i_timer_irq(1'b0),
|
||||
.i_wb_rdt(wb_rdt),
|
||||
.i_wb_ack(wb_ack),
|
||||
.o_wb_adr(wb_adr),
|
||||
.o_wb_dat(wb_dat),
|
||||
.o_wb_sel(wb_sel),
|
||||
.o_wb_we(wb_we),
|
||||
.o_wb_stb(wb_stb)
|
||||
);
|
||||
|
||||
wb_gpio_banks #(
|
||||
.BASE_ADDR(32'h40000000),
|
||||
.NUM_BANKS(4)
|
||||
) gpio (
|
||||
.i_wb_clk(i_clk),
|
||||
.i_wb_rst(i_rst),
|
||||
.i_wb_dat(wb_dat),
|
||||
.i_wb_adr(wb_adr),
|
||||
.i_wb_we(wb_we),
|
||||
.i_wb_stb(wb_stb),
|
||||
.i_wb_sel(wb_sel),
|
||||
.i_gpio(GPI),
|
||||
.o_wb_rdt(wb_rdt),
|
||||
.o_wb_ack(wb_ack),
|
||||
.o_gpio(GPO)
|
||||
);
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user