generated from efabless/caravel_user_project
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from IAmMarcelJung/fix/update_pins
Update IO pins to new fabric and also add all eFPGA fabric files
- Loading branch information
Showing
12 changed files
with
9,127 additions
and
1,190 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
module BlockRAM_1KB ( | ||
clk, | ||
rd_addr, | ||
rd_data, | ||
wr_addr, | ||
wr_data, | ||
C0, | ||
C1, | ||
C2, | ||
C3, | ||
C4, | ||
C5 | ||
); | ||
|
||
parameter READ_ADDRESS_MSB_FROM_DATALSB = 24; //default 24 means bits wr_data[25:24] will become bits [9:8] of read address | ||
parameter WRITE_ADDRESS_MSB_FROM_DATALSB = 16; //default 16 means bits wr_data[17:16] will become bits [9:8] of write address | ||
parameter WRITE_ENABLE_FROM_DATA = 20; //default 20 means bit wr_data[20] will become the dynamic writeEnable input | ||
input clk; | ||
input [7:0] rd_addr; | ||
output [31:0] rd_data; | ||
|
||
input [7:0] wr_addr; | ||
input [31:0] wr_data; | ||
|
||
input C0; //naming of these doesnt really matter | ||
input C1; // C0,C1 select write port width | ||
input C2; // C2,C3 select read port width | ||
input C3; | ||
input C4; //C4 selects the alwaysWriteEnable | ||
input C5; //C5 selects register bypass | ||
// NOTE, the read enable is currently constantly ON | ||
// NOTE, the R/W port on the standard cell is used only in write mode | ||
// NOTE, enable ports on the primitive RAM are active lows | ||
wire [1:0] rd_port_configuration; | ||
wire [1:0] wr_port_configuration; | ||
wire optional_register_enabled_configuration; | ||
wire alwaysWriteEnable; | ||
assign wr_port_configuration = {C0, C1}; | ||
assign rd_port_configuration = {C2, C3}; | ||
assign alwaysWriteEnable = C4; | ||
assign optional_register_enabled_configuration = C5; | ||
|
||
reg memWriteEnable; | ||
always @(*) begin // write enable | ||
if (alwaysWriteEnable) begin | ||
memWriteEnable = 0; // This RAM primitive is active low. | ||
end else begin | ||
memWriteEnable = (!(wr_data[WRITE_ENABLE_FROM_DATA])); // inverting the bit to make it active-high | ||
end | ||
end | ||
reg [ 3:0] mem_wr_mask; | ||
reg [31:0] muxedDataIn; | ||
|
||
wire [ 1:0] wr_addr_topbits; | ||
assign wr_addr_topbits = wr_data[WRITE_ADDRESS_MSB_FROM_DATALSB+1:WRITE_ADDRESS_MSB_FROM_DATALSB]; | ||
always @(*) begin //write port config -> mask + write data multiplex | ||
muxedDataIn = 32'dx; | ||
if (wr_port_configuration == 0) begin | ||
mem_wr_mask = 4'b1111; | ||
muxedDataIn = wr_data; | ||
end else if (wr_port_configuration == 1) begin | ||
if (wr_addr_topbits == 0) begin | ||
mem_wr_mask = 4'b0011; | ||
muxedDataIn[15:0] = wr_data[15:0]; | ||
end else begin | ||
mem_wr_mask = 4'b1100; | ||
muxedDataIn[31:16] = wr_data[15:0]; | ||
end | ||
end else if (wr_port_configuration == 2) begin | ||
if (wr_addr_topbits == 0) begin | ||
mem_wr_mask = 4'b0001; | ||
muxedDataIn[7:0] = wr_data[7:0]; | ||
end else if (wr_addr_topbits == 1) begin | ||
mem_wr_mask = 4'b0010; | ||
muxedDataIn[15:8] = wr_data[7:0]; | ||
end else if (wr_addr_topbits == 2) begin | ||
mem_wr_mask = 4'b0100; | ||
muxedDataIn[23:16] = wr_data[7:0]; | ||
end else begin | ||
mem_wr_mask = 4'b1000; | ||
muxedDataIn[31:24] = wr_data[7:0]; | ||
end | ||
end | ||
end | ||
wire [31:0] mem_dout; | ||
//dout0 is unused | ||
sram_1rw1r_32_256_8_sky130 memory_cell ( | ||
.clk0 (clk), | ||
.csb0 (memWriteEnable), | ||
.web0 (memWriteEnable), | ||
.wmask0(mem_wr_mask), | ||
.addr0 (wr_addr[7:0]), | ||
.din0 (muxedDataIn), | ||
.dout0 (), | ||
.clk1 (clk), | ||
.csb1 (1'b0), | ||
.addr1 (rd_addr[7:0]), | ||
.dout1 (mem_dout) | ||
); | ||
reg [1:0] rd_dout_sel; | ||
always @(posedge clk) begin | ||
rd_dout_sel <= wr_data[READ_ADDRESS_MSB_FROM_DATALSB+1:READ_ADDRESS_MSB_FROM_DATALSB]; | ||
end | ||
reg [31:0] rd_dout_muxed; | ||
always @(*) begin | ||
rd_dout_muxed[31:0] = mem_dout[31:0]; // a default value. Could be 32'dx if tools support it for logic saving! | ||
if (rd_port_configuration == 0) begin | ||
rd_dout_muxed[31:0] = mem_dout[31:0]; | ||
end else if (rd_port_configuration == 1) begin | ||
if (rd_dout_sel[0] == 0) begin | ||
rd_dout_muxed[15:0] = mem_dout[15:0]; | ||
end else begin | ||
rd_dout_muxed[15:0] = mem_dout[31:16]; | ||
end | ||
end else if (rd_port_configuration == 2) begin | ||
if (rd_dout_sel == 0) begin | ||
rd_dout_muxed[7:0] = mem_dout[7:0]; | ||
end else if (rd_dout_sel == 1) begin | ||
rd_dout_muxed[7:0] = mem_dout[15:8]; | ||
end else if (rd_dout_sel == 2) begin | ||
rd_dout_muxed[7:0] = mem_dout[23:16]; | ||
end else begin | ||
rd_dout_muxed[7:0] = mem_dout[31:24]; | ||
end | ||
end | ||
end | ||
reg [31:0] rd_dout_additional_register; | ||
always @(posedge clk) begin | ||
rd_dout_additional_register <= rd_dout_muxed; | ||
end | ||
reg [31:0] final_dout; | ||
assign rd_data = final_dout; | ||
always @(*) begin | ||
if (optional_register_enabled_configuration) begin | ||
final_dout = rd_dout_additional_register; | ||
end else begin | ||
final_dout = rd_dout_muxed; | ||
end | ||
end | ||
endmodule | ||
|
||
|
||
(* blackbox *) | ||
module sram_1rw1r_32_256_8_sky130 ( | ||
//`ifdef USE_POWER_PINS | ||
// vdd, | ||
// gnd, | ||
//`endif | ||
// Port 0: RW | ||
clk0, | ||
csb0, | ||
web0, | ||
wmask0, | ||
addr0, | ||
din0, | ||
dout0, | ||
// Port 1: R | ||
clk1, | ||
csb1, | ||
addr1, | ||
dout1 | ||
); | ||
|
||
parameter NUM_WMASKS = 4; | ||
parameter DATA_WIDTH = 32; | ||
parameter ADDR_WIDTH = 8; | ||
parameter RAM_DEPTH = 1 << ADDR_WIDTH; | ||
// FIXME: This delay is arbitrary. | ||
parameter DELAY = 3; | ||
//`ifdef USE_POWER_PINS | ||
// inout vdd; | ||
// inout gnd; | ||
//`endif | ||
input clk0; // clock | ||
input csb0; // active low chip select | ||
input web0; // active low write control | ||
input [NUM_WMASKS-1:0] wmask0; // write mask | ||
input [ADDR_WIDTH-1:0] addr0; | ||
input [DATA_WIDTH-1:0] din0; | ||
output [DATA_WIDTH-1:0] dout0; | ||
input clk1; // clock | ||
input csb1; // active low chip select | ||
input [ADDR_WIDTH-1:0] addr1; | ||
output [DATA_WIDTH-1:0] dout1; | ||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
module ConfigFSM ( | ||
CLK, | ||
resetn, | ||
WriteData, | ||
WriteStrobe, | ||
FSM_Reset, | ||
FrameAddressRegister, | ||
LongFrameStrobe, | ||
RowSelect | ||
); | ||
parameter NumberOfRows = 16; | ||
parameter RowSelectWidth = 5; | ||
parameter FrameBitsPerRow = 32; | ||
parameter desync_flag = 20; | ||
|
||
input CLK; | ||
input resetn; | ||
|
||
input [31:0] WriteData; | ||
input WriteStrobe; | ||
input FSM_Reset; | ||
|
||
output reg [FrameBitsPerRow-1:0] FrameAddressRegister; | ||
output reg LongFrameStrobe; | ||
output reg [RowSelectWidth-1:0] RowSelect; | ||
|
||
reg FrameStrobe; | ||
//signal FrameShiftState : integer range 0 to (NumberOfRows + 2); | ||
reg [4:0] FrameShiftState; | ||
|
||
//FSM | ||
reg [1:0] state; | ||
reg old_reset; | ||
always @(posedge CLK, negedge resetn) begin : P_FSM | ||
if (!resetn) begin | ||
old_reset <= 1'b0; | ||
state <= 2'b00; | ||
FrameShiftState <= 5'b00000; | ||
FrameAddressRegister <= 0; | ||
FrameStrobe <= 1'b0; | ||
end else begin | ||
old_reset <= FSM_Reset; | ||
FrameStrobe <= 1'b0; | ||
// we only activate the configuration after detecting a 32-bit aligned pattern "x"FAB0_FAB1" | ||
// this allows placing the com-port header into the file and we can use the same file for parallel or UART configuration | ||
// this also allows us to place whatever metadata, the only point to remeber is that the pattern/file needs to be 4-byte padded in the header | ||
if ((old_reset == 1'b0) && (FSM_Reset == 1'b1)) begin // reset all on ComActive posedge | ||
state <= 0; | ||
FrameShiftState <= 0; | ||
end else begin | ||
case (state) | ||
0: begin // unsynched | ||
if (WriteStrobe == 1'b1) begin // if writing enabled | ||
if (WriteData == 32'hFAB0_FAB1) begin // fire only after seeing pattern 0xFAB0_FAB1 | ||
state <= 1; //go to synched state | ||
end | ||
end | ||
end | ||
1: begin // SyncState read header | ||
if (WriteStrobe == 1'b1) begin // if writing enabled | ||
if (WriteData[desync_flag] == 1'b1) begin // desync | ||
state <= 0; //desynced | ||
end else begin | ||
FrameAddressRegister <= WriteData; | ||
FrameShiftState <= NumberOfRows; | ||
state <= 2; //writing frame data | ||
end | ||
end | ||
end | ||
2: begin | ||
if (WriteStrobe == 1'b1) begin // if writing enabled | ||
FrameShiftState <= FrameShiftState - 1; | ||
if (FrameShiftState == 1) begin // on last frame | ||
FrameStrobe <= 1'b1; //trigger FrameStrobe | ||
state <= 1; // we go to synched state waiting for next frame or desync | ||
end | ||
end | ||
end | ||
endcase | ||
end | ||
end | ||
end | ||
|
||
always @(*) begin | ||
if (WriteStrobe) begin // if writing active | ||
RowSelect = FrameShiftState; // we write the frame | ||
end else begin | ||
RowSelect = {RowSelectWidth{1'b1}}; //otherwise, we write an invalid frame | ||
end | ||
end | ||
|
||
reg oldFrameStrobe; | ||
always @(posedge CLK, negedge resetn) begin : P_StrobeREG | ||
if (!resetn) begin | ||
oldFrameStrobe <= 1'b0; | ||
LongFrameStrobe <= 1'b0; | ||
end else begin | ||
oldFrameStrobe <= FrameStrobe; | ||
LongFrameStrobe <= (FrameStrobe || oldFrameStrobe); | ||
end | ||
end //CLK | ||
|
||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
module Frame_Data_Reg ( | ||
FrameData_I, | ||
FrameData_O, | ||
RowSelect, | ||
CLK | ||
); | ||
parameter FrameBitsPerRow = 32; | ||
parameter RowSelectWidth = 5; | ||
parameter Row = 1; | ||
input [FrameBitsPerRow-1:0] FrameData_I; | ||
output reg [FrameBitsPerRow-1:0] FrameData_O; | ||
input [RowSelectWidth-1:0] RowSelect; | ||
input CLK; | ||
|
||
always @(posedge CLK) begin | ||
if (RowSelect == Row) FrameData_O <= FrameData_I; | ||
end //CLK | ||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
module Frame_Select ( | ||
FrameStrobe_I, | ||
FrameStrobe_O, | ||
FrameSelect, | ||
FrameStrobe | ||
); | ||
parameter MaxFramesPerCol = 20; | ||
parameter FrameSelectWidth = 5; | ||
parameter Col = 18; | ||
input [MaxFramesPerCol-1:0] FrameStrobe_I; | ||
output reg [MaxFramesPerCol-1:0] FrameStrobe_O; | ||
input [FrameSelectWidth-1:0] FrameSelect; | ||
input FrameStrobe; | ||
|
||
//FrameStrobe_O = 0; | ||
always @(*) begin | ||
if (FrameStrobe && (FrameSelect == Col)) FrameStrobe_O = FrameStrobe_I; | ||
else FrameStrobe_O = 'd0; | ||
end | ||
endmodule | ||
|
Oops, something went wrong.