OpenCores
URL https://opencores.org/ocsvn/rf6809/rf6809/trunk

Subversion Repositories rf6809

[/] [rf6809/] [trunk/] [rtl/] [noc/] [lib/] [random.sv] - Rev 22

Go to most recent revision | Compare with Previous | Blame | View Log

// ============================================================================
//        __
//   \\__/ o\    (C) 2011-2022  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//
// random.v
//     Multi-stream random number generator.
//
//
// This source file is free software: you can redistribute it and/or modify 
// it under the terms of the GNU Lesser General Public License as published 
// by the Free Software Foundation, either version 3 of the License, or     
// (at your option) any later version.                                      
//                                                                          
// This source file is distributed in the hope that it will be useful,      
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// GNU General Public License for more details.                             
//                                                                          
// You should have received a copy of the GNU General Public License        
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
//                      
//      Reg no.
//      0                        read: random output bits [31:0], write: gen next number 
//  1           random stream number
//  2           m_z seed setting bits [31:0]
//  3           m_w seed setting bits [31:0]
//
//  +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |WISHBONE Datasheet
//      |WISHBONE SoC Architecture Specification, Revision B.3
//      |
//      |Description:                                           Specifications:
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |General Description:                           random number generator
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |Supported Cycles:                                      SLAVE,READ/WRITE
//      |                                                                       SLAVE,BLOCK READ/WRITE
//      |                                                                       SLAVE,RMW
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |Data port, size:                                       16 bit
//      |Data port, granularity:                        16 bit
//      |Data port, maximum operand size:       16 bit
//      |Data transfer ordering:                        Undefined
//      |Data transfer sequencing:                      Undefined
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |Clock frequency constraints:           none
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |Supported signal list and                      Signal Name             WISHBONE equiv.
//      |cross reference to equivalent          ack_o                   ACK_O
//      |WISHBONE signals                                       adr_i[43:0]             ADR_I()
//      |                                                                       clk_i                   CLK_I
//      |                                   rst_i           RST_I()
//      |                                                                       dat_i(15:0)             DAT_I()
//      |                                                                       dat_o(15:0)             DAT_O()
//      |                                                                       cyc_i                   CYC_I
//      |                                                                       stb_i                   STB_I
//      |                                                                       we_i                    WE_I
//      |
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |Special requirements:
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// ============================================================================
//
// Uses George Marsaglia's multiply method
//
// m_w = <choose-initializer>;    /* must not be zero */
// m_z = <choose-initializer>;    /* must not be zero */
//
// uint get_random()
// {
//     m_z = 36969 * (m_z & 65535) + (m_z >> 16);
//     m_w = 18000 * (m_w & 65535) + (m_w >> 16);
//     return (m_z << 16) + m_w;  /* 32-bit result */
// }
//
`define TRUE    1'b1
`define FALSE   1'b0

module random(rst_i, clk_i, cs_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i, dat_o);
input rst_i;
input clk_i;
input cs_i;
input cyc_i;
input stb_i;
output reg ack_o;
input we_i;
input [3:0] adr_i;
input [11:0] dat_i;
output reg [11:0] dat_o;
parameter pAckStyle = 1'b0;

reg ack;
reg cs;
reg we;
reg [3:0] adr;
reg [11:0] dat;
always_ff @(posedge clk_i)
        cs <= cs_i && cyc_i && stb_i;
always_ff @(posedge clk_i)
        we <= we_i;
always_ff @(posedge clk_i)
        adr <= adr_i;
always_ff @(posedge clk_i)
        dat <= dat_i;

always_ff @(posedge clk_i)
        ack_o <= cs & cs_i & cyc_i & stb_i;
//always @*
//      ack_o <= cs ? ack : pAckStyle;

reg [9:0] stream;
reg [35:0] next_m_z;
reg [35:0] next_m_w;
reg [35:0] out;
reg wrw, wrz;
reg [35:0] w=32'd3,z=32'd17;
wire [35:0] m_zs;
wire [35:0] m_ws;
wire pe_we;

edge_det ued1 (.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(we), .pe(pe_we), .ne(), .ee());
rand_ram u1 (clk_i, wrw, stream, w, m_ws);
rand_ram u2 (clk_i, wrz, stream, z, m_zs);

always_comb
begin
        next_m_z = (18'h36969 * m_zs[17:0]) + m_zs[35:18];
        next_m_w = (18'h18000 * m_ws[17:0]) + m_ws[35:18];
end

reg [35:0] m_zsws;
always_comb
        m_zsws <= {m_zs[17:0],18'd0} + m_ws;

// Register read path
//
always_ff @(posedge clk_i)
if (cs_i)
        case(adr[3:0])
        4'd0:   dat_o <= 12'h0;
        4'd1: dat_o <= m_zsws[35:24];
        4'd2: dat_o <= m_zsws[23:12];
        4'd3:   dat_o <= m_zsws[11: 0];
        4'd5:   dat_o <= {2'h0,stream};
// Uncomment these for register read-back
//              3'd4:   dat_o <= m_z[31:16];
//              3'd5:   dat_o <= m_z[15: 0];
//              3'd6:   dat_o <= m_w[31:16];
//              3'd7:   dat_o <= m_w[15: 0];
        default:        dat_o <= 12'h000;
        endcase
else
        dat_o <= 12'h0;

// Register write path
//
always_ff @(posedge clk_i)
begin
        wrw <= `FALSE;
        wrz <= `FALSE;
        if (cs) begin
                if (pe_we)
                        case(adr[3:0])
                        4'd3:
                                begin
                                        z <= next_m_z;
                                        w <= next_m_w;
                                        wrw <= `TRUE;
                                        wrz <= `TRUE;
                                end
                        4'd5:   stream <= dat[9:0];
                        4'd8:   ;
                        4'd9:   z[35:24] <= dat;
                        4'd10:  z[23:12] <= dat;
                        4'd11:  begin z[11: 0] <= dat; wrz <= `TRUE; end
                        4'd12:  ;
                        4'd13:  w[35:24] <= dat;
                        4'd14:  w[23:12] <= dat;
                        4'd15:  begin w[11:0] <= dat; wrw <= `TRUE; end
                        endcase
        end
end

endmodule


// Tools were inferring a massive distributed ram so we help them out a bit by
// creating an explicit ram definition.

module rand_ram(clk, wr, ad, i, o);
input clk;
input wr;
input [9:0] ad;
input [35:0] i;
output [35:0] o;

reg [35:0] ri;
reg [9:0] regadr;
reg regwr;
(* RAM_STYLE="BLOCK" *)
reg [35:0] mem [0:1023];

always_ff @(posedge clk)
        regadr <= ad;
always_ff @(posedge clk)
        regwr <= wr;
always_ff @(posedge clk)
        ri <= i;
always_ff @(posedge clk)
        if (regwr)
                mem[regadr] <= ri;
assign o = mem[regadr];

endmodule

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.