diff options
author | matt | 2009-04-04 01:17:04 +0000 |
---|---|---|
committer | matt | 2009-04-04 01:17:04 +0000 |
commit | 0907e015a341269f1d9fdb556fcadd8c051c7f81 (patch) | |
tree | 06d8dd876bd5cba104c04ffaa987435e5762d850 /usrp2/fpga/simple_gemac/simple_gemac_wb.v | |
parent | d912b81bb3a71c66c4a5ba5d9a74e198d77a4d51 (diff) | |
download | gnuradio-0907e015a341269f1d9fdb556fcadd8c051c7f81.tar.gz gnuradio-0907e015a341269f1d9fdb556fcadd8c051c7f81.tar.bz2 gnuradio-0907e015a341269f1d9fdb556fcadd8c051c7f81.zip |
first cut at a wishbone interface and wrapping the core
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10762 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'usrp2/fpga/simple_gemac/simple_gemac_wb.v')
-rw-r--r-- | usrp2/fpga/simple_gemac/simple_gemac_wb.v | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/usrp2/fpga/simple_gemac/simple_gemac_wb.v b/usrp2/fpga/simple_gemac/simple_gemac_wb.v new file mode 100644 index 000000000..96189e1d9 --- /dev/null +++ b/usrp2/fpga/simple_gemac/simple_gemac_wb.v @@ -0,0 +1,134 @@ + +module wb_reg + #(parameter ADDR=0, + parameter DEFAULT=0) + (input clk, input rst, + input [5:0] adr, input wr_acc, + input [31:0] dat_i, output reg [31:0] dat_o); + + always @(posedge clk) + if(rst) + dat_o <= DEFAULT; + else if(wr_acc & (adr == ADDR)) + dat_o <= dat_i; + +endmodule // wb_reg + + + +module simple_gemac_wb + (input wb_clk, input wb_rst, + input wb_cyc, input wb_stb, input wb_ack, input wb_we, + input [7:0] wb_adr, input [31:0] wb_dat_i, output reg [31:0] wb_dat_o, + + inout mdio, output mdc, + output [47:0] ucast_addr, output [47:0] mcast_addr, + output pass_ucast, output pass_mcast, output pass_bcast, + output pass_pause, output pass_all, output pause_en ); + + wire wr_acc = wb_cyc & wb_stb & wb_we; + wire rd_acc = wb_cyc & wb_stb & ~wb_we; + + wire [5:0] misc_settings; + assign {pass_ucast, pass_mcast, pass_bcast, pass_pause, pass_all, pause_en} = misc_settings; + + wb_reg #(.ADDR(0),.DEFAULT(6'b111001)) + wb_reg_settings (.clk(wb_clk), .rst(wb_rst), .adr(wb_adr[7:2]), .dat_i(wb_dat_i), .dat_o(misc_settings) ); + wb_reg #(.ADDR(1),.DEFAULT(0)) + wb_reg_ucast_h (.clk(wb_clk), .rst(wb_rst), .adr(wb_adr[7:2]), .dat_i(wb_dat_i), .dat_o(ucast_addr[47:32]) ); + wb_reg #(.ADDR(2),.DEFAULT(0)) + wb_reg_ucast_l (.clk(wb_clk), .rst(wb_rst), .adr(wb_adr[7:2]), .dat_i(wb_dat_i), .dat_o(ucast_addr[31:0]) ); + wb_reg #(.ADDR(3),.DEFAULT(0)) + wb_reg_mcast_h (.clk(wb_clk), .rst(wb_rst), .adr(wb_adr[7:2]), .dat_i(wb_dat_i), .dat_o(mcast_addr[47:32]) ); + wb_reg #(.ADDR(4),.DEFAULT(0)) + wb_reg_mcast_l (.clk(wb_clk), .rst(wb_rst), .adr(wb_adr[7:2]), .dat_i(wb_dat_i), .dat_o(mcast_addr[31:0]) ); + + //MII to CPU + wire [7:0] Divider; // Divider for the host clock + wire [15:0] CtrlData; // Control Data (to be written to the PHY reg.) + wire [4:0] Rgad; // Register Address (within the PHY) + wire [4:0] Fiad; // PHY Address + wire NoPre; // No Preamble (no 32-bit preamble) + wire WCtrlData; // Write Control Data operation + wire RStat; // Read Status operation + wire ScanStat; // Scan Status operation + wire Busy; // Busy Signal + wire LinkFail; // Link Integrity Signal + wire Nvalid; // Invalid Status (qualifier for the valid scan result) + wire [15:0] Prsd; // Read Status Data (data read from the PHY) + wire WCtrlDataStart; // This signals resets the WCTRLDATA bit in the MIIM Command register + wire RStatStart; // This signal resets the RSTAT BIT in the MIIM Command register + wire UpdateMIIRX_DATAReg; // Updates MII RX_DATA register with read data + + // registers for controlling the MII interface + reg [2:0] MIICOMMAND; + wire [12:0] MIIADDRESS; + reg [15:0] MIIRX_DATA; + wire [2:0] MIISTATUS; + + wb_reg #(.ADDR(5),.DEFAULT(0)) + wb_reg_miimoder (.clk(wb_clk), .rst(wb_rst), .adr(wb_adr[7:2]), .dat_i(wb_dat_i), .dat_o({NoPre,Divider}) ); + + wb_reg #(.ADDR(6),.DEFAULT(0)) + wb_reg_miiaddr (.clk(wb_clk), .rst(wb_rst), .adr(wb_adr[7:2]), .dat_i(wb_dat_i), .dat_o(MIIADDRESS) ); + + wb_reg #(.ADDR(7),.DEFAULT(0)) + wb_reg_miidata (.clk(wb_clk), .rst(wb_rst), .adr(wb_adr[7:2]), .dat_i(wb_dat_i), .dat_o(CtrlData) ); + + // MIICOMMAND register - needs special treatment because of auto-resetting bits + always @ (posedge wb_clk) + if (wb_rst) + MIICOMMAND <= 0; + else + if (wr_acc & (wb_adr == 8'd8)) + MIICOMMAND <= wb_dat_i; + else + begin + if ( WCtrlDataStart ) + MIICOMMAND[2] <= 0; + if ( RStatStart ) + MIICOMMAND[1] <= 0; + end + + // MIIRX_DATA register + always @(posedge wb_clk) + if (wb_rst) + MIIRX_DATA <= 0; + else + if (UpdateMIIRX_DATAReg ) + MIIRX_DATA <= Prsd; + + // MIICOMMAND + assign WCtrlData = MIICOMMAND[2]; + assign RStat = MIICOMMAND[1]; + assign ScanStat = MIICOMMAND[0]; + // MIIADDRESS + assign Rgad = MIIADDRESS[12:8]; + assign Fiad = MIIADDRESS[4:0]; + // MIISTATUS + assign MIISTATUS[2:0] = { Nvalid, Busy, LinkFail }; + + eth_miim eth_miim + (.Clk(wb_clk), .Reset(wb_rst), + .Divider(Divider), .NoPre(NoPre), .CtrlData(CtrlData), .Rgad(Rgad), .Fiad(Fiad), + .WCtrlData(WCtrlData), .RStat(RStat), .ScanStat(ScanStat), .Mdio(mdio), .Mdc(mdc), + .Busy(Busy), .Prsd(Prsd), .LinkFail(LinkFail), .Nvalid(Nvalid), + .WCtrlDataStart(WCtrlDataStart), .RStatStart(RStatStart), + .UpdateMIIRX_DATAReg(UpdateMIIRX_DATAReg) ); + + always @(posedge wb_clk) + case(wb_adr) + 0 : wb_dat_o <= misc_settings; + 1 : wb_dat_o <= ucast_addr[47:32]; + 2 : wb_dat_o <= ucast_addr[31:0]; + 3 : wb_dat_o <= mcast_addr[47:32]; + 4 : wb_dat_o <= mcast_addr[31:0]; + 5 : wb_dat_o <= {NoPre,Divider}; + 6 : wb_dat_o <= MIIADDRESS; + 7 : wb_dat_o <= CtrlData; + 8 : wb_dat_o <= MIICOMMAND; + 9 : wb_dat_o <= MIISTATUS; + 10: wb_dat_o <= MIIRX_DATA; + endcase // case (wb_adr) + +endmodule // simple_gemac_wb |