feat: modify some ip impls

This commit is contained in:
maksyuki committed 2025-01-29 14:04:01 +08:00
1 parent 684a6655bb
commit b6a73f4843
3 files changed
+209 -23

No files matched your search

+172
View File
@@ -0,0 +1,172 @@
////////////////////////////////////////////////////////////////////
//// ////
//// I2C Master controller Top-level ////
//// ////
//// Modified from original project on OpenCores. ////
//// The top level routine modified to remove wishbone ////
//// interface to match Raven simple interfaces. For the ////
//// copyright and other original code, see source file ////
//// i2c_master_byte_ctrl.v. ////
//// ////
/////////////////////////////////////////////////////////////////////
module simple_i2c_master (
input clk, // master clock input
input resetn, // synchronous active low reset
input [ 2:0] reg_cfg1_we, // config register 1 write enable (3 bits)
input [31:0] reg_cfg1_di, // config register 1 data input
output [31:0] reg_cfg1_do, // config register 1 data output
input reg_cfg2_we, // config register 2 write enable (1 bit)
input [31:0] reg_cfg2_di, // config register 2 data input
output [31:0] reg_cfg2_do, // config register 2 data output
input reg_dat_we, // data write enable input (1 bit)
input reg_dat_re, // data read enable input
input [31:0] reg_dat_di, // data input
output [31:0] reg_dat_do, // data output
// I2C signals
// i2c clock line
input scl_pad_i, // SCL-line input
output scl_pad_o, // SCL-line output (always 1'b0)
output scl_padoeb_o, // SCL-line output enable (active low)
// i2c data line
input sda_pad_i, // SDA-line input
output sda_pad_o, // SDA-line output (always 1'b0)
output sda_padoeb_o, // SDA-line output enable (active low)
output irq_o // Interrupt for incoming data
);
// registers (in config register 1)
reg [15:0] prer; // clock prescale register
reg [ 7:0] ctr; // control register
// registers (in config register 2)
reg [ 7:0] cr; // command register
wire [ 7:0] sr; // status register
// registers (in data register)
reg [ 7:0] txr; // transmit register
wire [ 7:0] rxr; // receive register
// done signal: command completed, clear command register
wire done;
// core enable signal
wire core_en;
wire ien;
// status register signals
wire irxack;
reg rxack; // received aknowledge from slave
reg tip; // transfer in progress
reg irq_flag; // interrupt pending flag
wire i2c_busy; // bus busy (start signal detected)
wire i2c_al; // i2c bus arbitration lost
reg al; // status register arbitration lost bit
//
// module body
//
assign reg_cfg1_do = {8'b0, ctr, prer};
assign reg_cfg2_do = {24'b0, sr};
assign reg_dat_do = done ? rxr : ~0;
// generate registers
always @(posedge clk) begin
if (!resetn) begin
prer <= 16'hffff;
ctr <= 8'h0;
txr <= 8'h0;
end else begin
if (reg_cfg1_we[0]) prer[7:0] <= reg_cfg1_di[7:0];
if (reg_cfg1_we[1]) prer[15:8] <= reg_cfg1_di[15:8];
if (reg_cfg1_we[2]) ctr <= reg_cfg1_di[23:16];
// Upper 8 bits are not used
// Status register is not writeable
// Upper 24 bits are not used
if (reg_dat_we) txr <= reg_dat_di[7:0];
// Upper 24 bits are not used
end
end
// generate command register (special case)
always @(posedge clk) begin
if (!resetn) begin
cr <= 8'h0;
end else if (reg_cfg2_we) begin
if (core_en) cr <= reg_cfg2_di[7:0];
end else begin
if (done | i2c_al) cr[7:4] <= 4'h0; // clear command bits when done
// or when aribitration lost
cr[2:1] <= 2'b0; // reserved bits
cr[0] <= 1'b0; // clear IRQ_ACK bit
end
end
// decode command register
wire sta = cr[7];
wire sto = cr[6];
wire rd = cr[5];
wire wr = cr[4];
wire ack = cr[3];
wire iack = cr[0];
// decode control register
assign core_en = ctr[7];
assign ien = ctr[6];
// hook up byte controller block
i2c_master_byte_ctrl byte_controller (
.clk (clk),
.nReset (resetn),
.ena (core_en),
.clk_cnt (prer),
.start (sta),
.stop (sto),
.read (rd),
.write (wr),
.ack_in (ack),
.din (txr),
.cmd_ack (done),
.ack_out (irxack),
.dout (rxr),
.i2c_busy(i2c_busy),
.i2c_al (i2c_al),
.scl_i (scl_pad_i),
.scl_o (scl_pad_o),
.scl_oen (scl_padoeb_o),
.sda_i (sda_pad_i),
.sda_o (sda_pad_o),
.sda_oen (sda_padoeb_o)
);
// status register block + interrupt request signal
always @(posedge clk)
if (!resetn) begin
al <= 1'b0;
rxack <= 1'b0;
tip <= 1'b0;
irq_flag <= 1'b0;
end else begin
al <= i2c_al | (al & ~sta);
rxack <= irxack;
tip <= (rd | wr);
irq_flag <= (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated
end
// interrupt signal is only generated when IEN
// (interrupt enable bit) is set
assign irq_o = irq_flag && ien;
// assign status register bits
assign sr[7] = rxack;
assign sr[6] = i2c_busy;
assign sr[5] = al;
assign sr[4:2] = 3'h0; // reserved
assign sr[1] = tip;
assign sr[0] = irq_flag;
endmodule
+7 -6
View File
@@ -1,7 +1,7 @@
/*
* PicoSoC - A simple example SoC using PicoRV32
*
* Copyright (C) 2017 Claire Xenia Wolf <claire@yosyshq.com>
* Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -17,9 +17,7 @@
*
*/
module simpleuart #(
parameter integer DEFAULT_DIV = 1
) (
module simpleuart (
input clk,
input resetn,
output ser_tx,
@@ -31,7 +29,8 @@ module simpleuart #(
input reg_dat_re,
input [31:0] reg_dat_di,
output [31:0] reg_dat_do,
output reg_dat_wait
output reg_dat_wait,
output irq_out
);
reg [31:0] cfg_divider;
@@ -51,9 +50,11 @@ module simpleuart #(
assign reg_dat_wait = reg_dat_we && (send_bitcnt || send_dummy);
assign reg_dat_do = recv_buf_valid ? recv_buf_data : ~0;
assign irq_out = recv_buf_valid;
always @(posedge clk) begin
if (!resetn) begin
cfg_divider <= DEFAULT_DIV;
cfg_divider <= 1;
end else begin
if (reg_div_we[0]) cfg_divider[7:0] <= reg_div_di[7:0];
if (reg_div_we[1]) cfg_divider[15:8] <= reg_div_di[15:8];
+30 -17
View File
@@ -1,7 +1,7 @@
/*
* PicoSoC - A simple example SoC using PicoRV32
*
* Copyright (C) 2017 Claire Xenia Wolf <claire@yosyshq.com>
* Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -24,12 +24,19 @@ module spimemio (
output ready,
input [23:0] addr,
output reg [31:0] rdata,
input pass_thru,
input pass_thru_csb,
input pass_thru_sck,
input pass_thru_sdi,
output pass_thru_sdo,
output flash_csb,
output flash_clk,
output flash_io0_oe,
output flash_io1_oe,
output flash_io2_oe,
output flash_io3_oe,
output flash_csb_oeb,
output flash_clk_oeb,
output flash_io0_oeb,
output flash_io1_oeb,
output flash_io2_oeb,
output flash_io3_oeb,
output flash_io0_do,
output flash_io1_do,
output flash_io2_do,
@@ -85,7 +92,7 @@ module spimemio (
assign cfgreg_do[20] = config_cont;
assign cfgreg_do[19:16] = config_dummy;
assign cfgreg_do[15:12] = 0;
assign cfgreg_do[11:8] = {flash_io3_oe, flash_io2_oe, flash_io1_oe, flash_io0_oe};
assign cfgreg_do[11:8] = {~flash_io3_oeb, ~flash_io2_oeb, ~flash_io1_oeb, ~flash_io0_oeb};
assign cfgreg_do[7:6] = 0;
assign cfgreg_do[5] = flash_csb;
assign cfgreg_do[4] = flash_clk;
@@ -150,25 +157,30 @@ module spimemio (
xfer_io3_90 <= xfer_io3_do;
end
assign flash_csb = config_en ? xfer_csb : config_csb;
assign flash_clk = config_en ? xfer_clk : config_clk;
assign flash_csb = pass_thru ? pass_thru_csb : (config_en ? xfer_csb : config_csb);
assign flash_clk = pass_thru ? pass_thru_sck : (config_en ? xfer_clk : config_clk);
assign flash_csb_oeb = pass_thru ? 1'b0 : ~resetn ? 1'b1 : 1'b0;
assign flash_clk_oeb = pass_thru ? 1'b0 : ~resetn ? 1'b1 : 1'b0;
assign flash_io0_oe = config_en ? xfer_io0_oe : config_oe[0];
assign flash_io1_oe = config_en ? xfer_io1_oe : config_oe[1];
assign flash_io2_oe = config_en ? xfer_io2_oe : config_oe[2];
assign flash_io3_oe = config_en ? xfer_io3_oe : config_oe[3];
assign flash_io0_oeb = pass_thru ? 1'b0 : ~resetn ? 1'b1 : (config_en ? ~xfer_io0_oe : ~config_oe[0]);
assign flash_io1_oeb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? ~xfer_io1_oe : ~config_oe[1]);
assign flash_io2_oeb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? ~xfer_io2_oe : ~config_oe[2]);
assign flash_io3_oeb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? ~xfer_io3_oe : ~config_oe[3]);
assign flash_io0_do = config_en ? (config_ddr ? xfer_io0_90 : xfer_io0_do) : config_do[0];
assign flash_io0_do = pass_thru ? pass_thru_sdi : (config_en ? (config_ddr ? xfer_io0_90 : xfer_io0_do) : config_do[0]);
assign flash_io1_do = config_en ? (config_ddr ? xfer_io1_90 : xfer_io1_do) : config_do[1];
assign flash_io2_do = config_en ? (config_ddr ? xfer_io2_90 : xfer_io2_do) : config_do[2];
assign flash_io3_do = config_en ? (config_ddr ? xfer_io3_90 : xfer_io3_do) : config_do[3];
assign pass_thru_sdo = pass_thru ? flash_io1_di : 1'b0;
wire xfer_dspi = din_ddr && !din_qspi;
wire xfer_ddr = din_ddr && din_qspi;
spimemio_xfer xfer (
.clk (clk),
.resetn (xfer_resetn),
.resetn (resetn),
.xfer_resetn (xfer_resetn),
.din_valid (din_valid),
.din_ready (din_ready),
.din_data (din_data),
@@ -374,6 +386,7 @@ endmodule
module spimemio_xfer (
input clk,
resetn,
xfer_resetn,
input din_valid,
output din_ready,
@@ -435,9 +448,9 @@ module spimemio_xfer (
xfer_tag_q <= xfer_tag;
end
assign din_ready = din_valid && resetn && next_fetch;
assign din_ready = din_valid && xfer_resetn && next_fetch;
assign dout_valid = (xfer_ddr_q ? fetch && !last_fetch : next_fetch && !fetch) && resetn;
assign dout_valid = (xfer_ddr_q ? fetch && !last_fetch : next_fetch && !fetch) && xfer_resetn;
assign dout_data = ibuffer;
assign dout_tag = xfer_tag_q;
@@ -532,7 +545,7 @@ module spimemio_xfer (
end
always @(posedge clk) begin
if (!resetn) begin
if (!resetn || !xfer_resetn) begin
fetch <= 1;
last_fetch <= 1;
flash_csb <= 1;