Created
November 13, 2012 07:34
-
-
Save wnew/4064496 to your computer and use it in GitHub Desktop.
Parametrised BRAM wishbone bus interface
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//============================================================================// | |
// // | |
// Parameterize BRAM with wishbone interface // | |
// // | |
// Module name: bram_wb // | |
// Desc: parameterized dual-port bram with a wishbone interface on one // | |
// port. // | |
// Date: June 2012 // | |
// Developer: Wesley New // | |
// Licence: GNU General Public License ver 3 // | |
// Notes: // | |
// // | |
//============================================================================// | |
module bram_wb #( | |
//============= | |
// Parameters | |
//============= | |
parameter DEV_BASE_ADDR = 0, | |
parameter DEV_HIGH_ADDR = 32, | |
parameter BUS_DATA_WIDTH = 32, | |
parameter BUS_ADDR_WIDTH = 8, | |
parameter BUS_BE_WIDTH = 4, | |
parameter RAM_ADDR_WIDTH = 8, | |
parameter SLEEP_COUNT = 4 | |
) ( | |
//=============== | |
// Fabric Ports | |
//=============== | |
input fabric_clk, | |
input fabric_rst, | |
input fabric_we, | |
input [RAM_ADDR_WIDTH-1:0] fabric_addr, | |
input [RAM_DATA_WIDTH-1:0] fabric_data_in, | |
output [RAM_DATA_WIDTH-1:0] fabric_data_out, | |
//================= | |
// Wishbone Ports | |
//================= | |
input wire wbs_clk_i, | |
input wire wbs_rst_i, | |
input wire wbs_cyc_i, | |
input wire wbs_stb_i, | |
input wire wbs_we_i, | |
input wire [BUS_BE_WIDTH-1:0] wbs_sel_i, | |
input wire [BUS_ADDR_WIDTH-1:0] wbs_adr_i, | |
input wire [BUS_DATA_WIDTH-1:0] wbs_dat_i, | |
output reg [BUS_DATA_WIDTH-1:0] wbs_dat_o, | |
output reg wbs_ack_o | |
); | |
//=================== | |
// Local Parameters | |
//=================== | |
localparam RAM_DATA_WIDTH = BUS_ADDR_WIDTH; | |
localparam DATA_DEPTH = 2 ** RAM_ADDR_WIDTH; | |
//====================== | |
// Local Reg and Wires | |
//====================== | |
wire [RAM_DATA_WIDTH-1:0] read_data; | |
reg [RAM_DATA_WIDTH-1:0] write_data; | |
reg [RAM_ADDR_WIDTH-1:0] ram_adr; | |
reg [3:0] ram_sleep; | |
reg en_ram; | |
//================ | |
// BRAM instance | |
//================ | |
bram_sync_dp #( | |
.RAM_DATA_WIDTH (RAM_DATA_WIDTH), | |
.RAM_ADDR_WIDTH (RAM_ADDR_WIDTH) | |
) bram_inst ( | |
.rst (wbs_rst_i || fabric_rst), | |
.en (en_ram), | |
.a_clk (fabric_clk), | |
.a_wr (fabric_we), | |
.a_addr (fabric_addr), | |
.a_data_in (fabric_data_in), | |
.a_data_out (fabric_data_out), | |
.b_clk (wbs_clk_i), | |
.b_wr (wbs_we_i), | |
.b_addr (ram_adr), | |
.b_data_in (write_data), | |
.b_data_out (read_data) | |
); | |
wire adr_match = wbs_adr_i >= DEV_BASE_ADDR && wbs_adr_i <= DEV_HIGH_ADDR; | |
// TODO: make sure the logic below is working!!!! | |
//================= | |
// Wishbone Logic | |
//================= | |
always @ (posedge wbs_clk_i) begin | |
if (fabric_rst || wbs_rst_i) begin | |
wbs_dat_o <= 32'h00000000; | |
wbs_ack_o <= 0; | |
ram_sleep <= SLEEP_COUNT; | |
ram_adr <= 0; | |
en_ram <= 0; | |
end | |
else begin | |
//when the master acks our ack, then put our ack down | |
if (wbs_ack_o & ~wbs_stb_i) begin | |
wbs_ack_o <= 0; | |
en_ram <= 0; | |
end | |
if (adr_match & wbs_stb_i & wbs_cyc_i) begin | |
//master is requesting somethign | |
en_ram <= 1; | |
ram_adr <= wbs_adr_i[BUS_ADDR_WIDTH-1:0]; | |
if (wbs_we_i) begin | |
//write request | |
//the bram module will handle all the writes | |
write_data <= wbs_dat_i; | |
//$display ("write a:%h, d:%h", wbs_adr_i[ADDR_WIDTH:0], wbs_dat_i); | |
end | |
else begin | |
//read request | |
wbs_dat_o <= read_data; | |
//wbs_dat_o <= wbs_adr_i; | |
//$display ("read a:%h, d:%h", wbs_adr_i[ADDR_WIDTH:0], read_data); | |
end | |
if (ram_sleep > 0) begin | |
ram_sleep <= ram_sleep - 1; | |
end | |
else begin | |
wbs_ack_o <= 1; | |
ram_sleep <= SLEEP_COUNT; | |
end | |
end | |
end | |
end | |
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//============================================================================// | |
// // | |
// BRAM wishbone test bench // | |
// // | |
// Module name: bram_wb_tb // | |
// Desc: runs and tests the bram_wb module, and provides and interface // | |
// to test the module from Python (MyHDL) // | |
// This uses a dual port bram with one ports connected to the // | |
// wishbone bus and the other to the fabric // | |
// Date: June 2012 // | |
// Developer: Wesley New // | |
// Licence: GNU General Public License ver 3 // | |
// Notes: This only tests the basic functionality of the module, more // | |
// comprehensive testing is done in the python test file // | |
// // | |
//============================================================================// | |
module bram_wb_tb; | |
//===================== | |
// local wires & regs | |
//===================== | |
reg wbs_clk_i; | |
reg wbs_rst_i; | |
reg wbs_cyc_i; | |
reg wbs_stb_i; | |
reg wbs_we_i; | |
reg [3:0] wbs_sel_i; | |
reg [7:0] wbs_adr_i; | |
reg [31:0] wbs_dat_i; | |
wire [31:0] wbs_dat_o; | |
wire wbs_ack_o; | |
reg fabric_clk; | |
reg fabric_rst; | |
reg fabric_we; | |
reg [7:0] fabric_addr; | |
reg [31:0] fabric_data_in; | |
wire [31:0] fabric_data_out; | |
//===================================== | |
// instance, "(d)esign (u)nder (t)est" | |
//===================================== | |
bram_wb #( | |
.DATA_WIDTH (32), | |
.ADDR_WIDTH (8), | |
.SLEEP_COUNT (4) | |
//.C_BASEADDR (32'h00000000), | |
//.C_HIGHADDR (32'h0000FFFF) | |
) dut ( | |
.fabric_clk (fabric_clk), | |
.fabric_rst (fabric_rst), | |
.fabric_we (fabric_we), | |
.fabric_addr (fabric_addr), | |
.fabric_data_in (fabric_data_in), | |
.fabric_data_out (fabric_data_out), | |
.wbs_clk_i (wbs_clk_i), | |
.wbs_rst_i (wbs_rst_i), | |
.wbs_cyc_i (wbs_cyc_i), | |
.wbs_stb_i (wbs_stb_i), | |
.wbs_we_i (wbs_we_i), | |
.wbs_adr_i (wbs_adr_i), | |
.wbs_dat_i (wbs_dat_i), | |
.wbs_dat_o (wbs_dat_o), | |
.wbs_ack_o (wbs_ack_o) | |
); | |
//============== | |
// Initialize | |
//============== | |
initial | |
begin | |
$dumpvars; | |
wbs_clk_i = 0; | |
wbs_sel_i = 4'hE; | |
wbs_stb_i = 1; | |
wbs_cyc_i = 1; | |
wbs_we_i = 1; | |
wbs_adr_i = 8'h00; | |
wbs_dat_i = 32'hEEEEEEEE; | |
#5 | |
wbs_stb_i = 0; | |
wbs_cyc_i = 0; | |
#5 | |
wbs_adr_i = 8'h01; | |
wbs_stb_i = 1; | |
wbs_cyc_i = 1; | |
wbs_we_i = 0; | |
#20 $finish; | |
end | |
//===================== | |
// Simulate the Clock | |
//===================== | |
always #1 | |
wbs_clk_i = ~wbs_clk_i; | |
`endif | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment